account.units.added
A connected Booking.com Extranet login gained a property, or a room on a property it already had. Map the new units so their bookings, messages and reviews import.
When it fires
One Extranet login covers every property its Booking.com user can see. When the hotel adds the same user to another property, Repull finds it the next time it reads the login's properties, and sends one event per property with its new rooms. It is not sent for the properties a fresh connection starts with (connect.session.completed covers those), and the same rooms are never announced twice. hotels[].isNew is false when rooms were added to a property the login already had. Today only Booking.com Extranet logins send it.
Payload
Every delivery uses the same outer envelope (event, eventId, apiVersion, timestamp, data). Dedupe on eventId — it stays stable across retries and replays, while the X-Repull-Delivery-Id header changes on every attempt.
{
"event": "account.units.added",
"eventId": "3f1c9a2e-8b7d-4c6a-9e0f-1a2b3c4d5e6f",
"apiVersion": "2026-04",
"timestamp": "2026-05-01T12:34:56.000Z",
"data": {
"workspaceId": 1204,
"provider": "booking_extranet",
"accountId": "20123456",
"connectionId": "482",
"handle": "booking_extranet:20123456",
"hotels": [
{
"hotelId": "1234567",
"name": "Old Town Suites",
"isNew": true
}
],
"units": [
{
"unitId": "1456",
"name": "Double Room",
"hotelId": "1234567",
"roomId": "123456701",
"mapped": false,
"listingId": null
},
{
"unitId": "1457",
"name": "Twin Room",
"hotelId": "1234567",
"roomId": "123456702",
"mapped": false,
"listingId": null
}
],
"addedAt": "2026-11-12T16:40:00.000Z",
"nextSteps": [
{
"method": "GET",
"path": "/v1/connections/booking_extranet:20123456/units",
"description": "List the units with mapping suggestions."
},
{
"method": "POST",
"path": "/v1/connections/booking_extranet:20123456/mappings",
"description": "Map each new unit to a listing (or create one) so its bookings, messages and reviews import."
}
]
}
}Verifying signatures
Every delivery includes a timestamped X-Repull-Signature header of the form t=<unix_ts>,v1=<hex>, where v1 is HMAC-SHA256(signing_secret, `${t}.${raw_body}`). Verify it before processing — see Verify Signatures for full Node.js and Python examples.
Use the raw body
Example handler
if (event.event === 'account.units.added') {
const { hotels, units, nextSteps } = event.data
// nextSteps carries the mappings path for this connection.
const mapPath = nextSteps.find((s) => s.method === 'POST').path
// Create a listing for each new room (or pass a listingId to map it to one you have):
await repull.post(mapPath, {
mappings: units.map((u) => ({ unitId: u.unitId, create: true })),
})
notify(`New on Booking.com: ${hotels[0].name} (${units.length} rooms)`)
}Common patterns
- Show the user a "new property found" prompt that lists
unitsand lets them pick a listing for each, thenPOST /v1/connections/{id}/mappings. - Call
GET /v1/connections/{id}/unitsfor mapping suggestions (suggested_listing_id) before asking the user. - Route it to the right end customer by
account.externalAccountId— the Extranet login — like every other event.
Related
Tip: Acknowledge with a 2xx status within 10 seconds. Failed deliveries are retried up to 5 times with exponential backoff.Webhook reliability →