Update a booking
Change a booking you created. Send only what changed. Moving dates or units re-checks inventory, and a conflict leaves the booking exactly as it was.
Every field is optional; send the subset you are changing. The response is the full booking object after the change.
Body
Body
| Field | Type | Required | Description |
|---|---|---|---|
units
|
array | Optional | 1 to 20 entries. Sending this replaces the unit list, and re-allocates. |
units[].inventory_id
|
integer | Optional | Pin a Doorloom unit. |
units[].external_unit_id
|
string | Optional | Pin a unit by your alias. Max 128 characters. |
units[].adults
|
integer |
required with units
|
1 to 50. |
units[].children
|
integer | Optional | 0 to 50. |
units[].meal_plan
|
string | Optional | EP, CP, MP or AP. |
units[].stay_price
|
number | Optional | Room money for this unit across the stay. |
check_in
|
string | Optional | YYYY-MM-DD. Must be sent together with check_out. |
check_out
|
string | Optional | YYYY-MM-DD. Must be after check_in. |
guest
|
object | Optional | Lead guest details. |
guest.name
|
string | Optional | Max 255 characters. |
guest.phone_code
|
string | Optional | Max 8 characters. |
guest.mobile
|
string | Optional | Max 20 characters. |
guest.email
|
string | Optional | Valid email, max 255 characters. |
guest.country
|
string | Optional | Max 64 characters. |
pricing
|
object | Optional | Revised pricing. |
pricing.total
|
number | Optional | The new booking total. |
pricing.currency
|
string | Optional | Must be INR if sent. |
pricing.includes_gst
|
boolean | Optional | Whether total includes GST. |
pricing.breakdown
|
object | Optional | Free-form; stored verbatim. |
payment
|
object | Optional | Revised payment state. |
payment.status
|
string | Optional | paid, partial or unpaid. |
payment.amount_collected
|
number | Optional | Updates the advance recorded. |
payment.collected_by
|
string | Optional | partner or host. |
payment.reference
|
string | Optional | Max 128 characters. |
source
|
object | Optional | Only the reference is patchable. |
source.reference
|
string | Optional | Max 128 characters. |
status
|
string | Optional | confirmed or pending. Cancel through the cancel endpoint, not here. |
notes
|
string | Optional | Max 2000 characters. |
source.channel cannot be changed
source.reference is patchable;
source.channel is silently not accepted here. If the channel is genuinely wrong,
cancel and re-create.The property cannot be changed either. A booking that needs to move to a different property is a cancel plus a create.
Dates and units re-check inventory
Changing check_in and check_out, or changing units,
triggers a fresh allocation. The check excludes the booking's own current hold,
so extending a stay into a night that only this booking occupies works as you would expect.
If the new shape does not fit, the call fails with 409 UNAVAILABLE and
the booking is left completely untouched — dates, units and revision all
unchanged. As with create, a pinned unit that is taken is refused rather than swapped.
curl -X PATCH https://api.doorloom.com/api/integrations/v1/bookings/55231 \
-H "Authorization: Bearer $DOORLOOM_API_KEY" \
-H "Content-Type: application/json" \
-H "If-Match: 2" \
-d '{
"check_in": "2026-10-13",
"check_out": "2026-10-16",
"pricing": { "total": 27900 }
}'
Optimistic concurrency with If-Match
Send If-Match: <revision>, using the revision from the last
representation you read. If the booking has changed since, the call fails with
412 REVISION_MISMATCH and tells you the current revision.
{
"success": false,
"code": "REVISION_MISMATCH",
"message": "The booking was modified since you last read it.",
"errors": {
"current_revision": 4
}
}
Re-read the booking, re-apply your change on top of what is now there, and retry.
The header is optional. Omit it and your write always wins. Use it whenever the host can edit the same booking in the Doorloom app — which is to say, almost always. The revision increments on host-side edits too, which is exactly what makes it useful.
No idempotency key here
PATCH is naturally idempotent: applying the same field values twice reaches the same
state. Only create takes an
Idempotency-Key.Errors
Errors
| Status | Code | Meaning |
|---|---|---|
| 422 | VALIDATION_FAILED |
The request body failed validation. errors is Laravel's field bag: an object keyed by field path, each holding an array of messages. |
| 409 | BOOKING_CANCELLED |
A cancelled booking is terminal. It cannot be modified or un-cancelled. |
| 412 | REVISION_MISMATCH |
You sent If-Match and the booking has changed since you read it. The revision increments on every change, including host-side edits made in the Doorloom app. |
| 422 | PROPERTY_NOT_MAPPED |
The property reference is missing, unknown, or outside your integration's coverage. Coverage is set by Doorloom staff and only ever includes properties the brand owner owns outright, never cohosted ones. |
| 422 | UNIT_NOT_MAPPED |
A units[] line names a unit alias Doorloom does not know, or one that belongs to a different property. |
| 422 | UNIT_INACTIVE |
The unit is mapped but no longer sellable — deactivated or deleted by the host. |
| 409 | UNAVAILABLE |
There is no free unit for the whole stay, or a unit you pinned is taken. Nothing was written. Doorloom never silently swaps a pinned unit for another. |
| 404 | NOT_FOUND |
No such booking or property for this integration. Another integration's booking is not found rather than forbidden, so ids cannot be probed across partners. |
| 429 | RATE_LIMITED |
You exceeded one of the rate limits. The standard Retry-After and X-RateLimit-* headers are set on the response. |
What happens afterwards
You receive a
booking.changed
event with origin: "partner" and the incremented revision, plus an
availability.changed for the property if inventory moved.