Update Booking.com Pricing
Set Booking.com rates per room and rate plan, at an explicit occupancy, with length-of-stay and arrival restrictions sent in the same call. For a nightly price on every connected channel at once, use PUT /v1/availability/{propertyId} instead.
/v1/channels/booking/availabilityParameters
typestringRequiredrates | availability | derived-pricing
property_idstring | integerRequiredBooking.com property id, connected to your workspace.
updatesarrayRequiredFor rates: { roomId, rateId, dateRange: { start, end }, price, currency, occupancy?, restrictions? } per item. Get roomId / rateId from GET /v1/channels/booking/properties/{id}/rooms.
verifybooleanRead the dates back from Booking.com after the write and report whether the pushed prices are live. Defaults to true; false returns as soon as Booking.com acknowledges and reports applied: "unverified".
Occupancy is part of the price
Booking.com does not store "the price of this night". It stores a price for a night at a party size — the occupancy — on one rate plan. So occupancy is a key, not a preference: it decides which price you are overwriting. Every rate amount goes out with one.
- Send an occupancy above the maximum the rate plan itself prices at, and Booking.com accepts the request but declines the amount without saying so. The night keeps whatever it held before — often
0.00— and the acknowledgement looks identical to a successful write. - Send an occupancy below it and Booking.com answers
400. The published price does not change. - Omit
occupancyand it is resolved from Booking.com's own data for that (room, rate plan) pair. The response echoes both the value used and where it came from:occupancy[].value, withoccupancy[].sourceofrequest,rate_planorroom. - When it cannot be resolved for a pair, the write is refused with
422namingupdates[0].occupancy. A rate amount is never sent blind. - The guest capacity on your own listing is not an input. The number that governs is the one Booking.com holds for the rate plan — read it from
GET /v1/channels/booking/properties/{id}/rooms.
Dates are inclusive at both ends
dateRange.start and dateRange.end are both nights that get written — on rates, on availability and on restrictions alike. To price a single night, send the same date twice. An end set one day past the last night you meant to touch re-prices a night you did not intend to.
# One night — 2026-11-04
"dateRange": { "start": "2026-11-04", "end": "2026-11-04" }
# Four nights — 2026-11-04, 2026-11-05, 2026-11-06 and 2026-11-07
"dateRange": { "start": "2026-11-04", "end": "2026-11-07" }Inventory is a separate write
A rates update carries prices and restrictions only. roomsToSell sent on one is refused with 422 inventory_not_in_rate_update, naming updates[0].roomsToSell, and nothing is pushed.
- Rooms to sell and the stop-sell flag belong to
type: "availability"on this same endpoint, asavailableRoomsandclosed. See Push Availability to Booking.com. - The two writes are independent. Pricing a night does not open it for sale, and opening it does not price it.
Whether the price actually landed
Booking.com usually answers a rate write with a bare acknowledgement that carries no per-date status — the body is literally {"ok": ""}. That is a receipt for the request, not a confirmation of the price, and it is no longer reported as "all updates applied". applied says which of four things happened:
verified— the dates were read back from Booking.com and every pushed price is live.unverified— Booking.com acknowledged the write and the read-back was skipped or unavailable. This is an unknown, not a failure: the price may well be live, but nothing here proves it.mismatch— the read-back shows at least one date that did not take the pushed price.verification.datesnames them, with what Booking.com holds instead. An occupancy the rate plan does not price at is the usual cause.rejected— Booking.com returned errors.errors[]carries them and nothing was published.
The read-back
Booking.com applies a write asynchronously, so the read-back waits a short settle delay before asking for the same dates again. It costs one extra Booking.com read per call.
- Send
"verify": falseto skip it — useful for a long backfill you intend to reconcile separately. The call then returns as soon as Booking.com acknowledges, and reportsapplied: "unverified". - A skipped or unavailable read-back never reports
verified.verificationcarries the reason it did not run. - Reconcile at any time with
GET /v1/channels/booking/availability?property_id=1234567&start_date=2026-11-04&number_of_days=1.
Notes
- Scoped to your workspace: a Booking.com property id that is not connected to your workspace returns
404 not_found, the same answer as an id that does not exist. restrictionsacceptsminStay,maxStay,minStayArrival,maxStayArrival,closedToArrivalandclosedToDeparture. Omit a field to leave that restriction unchanged.exactStayArrival,minAdvanceResandmaxAdvanceResare refused with422 restriction_not_supported— Booking.com has no way to receive them, and they are refused rather than silently dropped.- A price and a restriction are two writes on Booking.com's side, so the response reports them separately in
priceandrestrictions.appliedispartialwhen one lands and the other does not — that is a 200, not an error, andrestrictions.rejection.messagecarries Booking.com's own reason. See Minimum Stay & Restrictions. - The affected nights are read back off Booking.com after the write, so
appliedsaysverifiedormismatchrather than echoing an acknowledgement. Sendverify: falseto skip it;appliedis thenunverified. - A rate amount is written against a party size. Send
occupancy, or omit it and Repull resolves it from Booking.com's own data and echoes it back inoccupancy[]. - A listing-keyed equivalent is
GET/PUT /v1/channels/booking/listings/{id}/pricing, which takes the Repull listing id.
Example
# One night, priced for a party of four
curl -X PUT https://api.repull.dev/v1/channels/booking/availability \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "rates",
"property_id": "1234567",
"updates": [
{
"roomId": "123456701",
"rateId": "98765",
"dateRange": { "start": "2026-11-04", "end": "2026-11-04" },
"price": 180,
"currency": "USD",
"occupancy": 4
}
]
}'
# Seven nights at a 2-night minimum, with the occupancy resolved from the rate plan
curl -X PUT https://api.repull.dev/v1/channels/booking/availability \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "rates",
"property_id": "1234567",
"updates": [
{
"roomId": "123456701",
"rateId": "98765",
"dateRange": { "start": "2026-07-01", "end": "2026-07-07" },
"price": 180,
"currency": "USD",
"restrictions": { "minStay": 2 }
}
]
}'
# Skip the read-back on a backfill you will reconcile separately
curl -X PUT https://api.repull.dev/v1/channels/booking/availability \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"type": "rates", "verify": false, "property_id": "1234567", "updates": [{"roomId": "123456701", "rateId": "98765", "dateRange": {"start": "2027-01-05", "end": "2027-01-05"}, "price": 210, "currency": "USD", "occupancy": 4}]}'Response
// 200 — the price was pushed and read back live
{
"requested": 1,
"occupancy": [
{ "roomId": "123456701", "rateId": "98765", "value": 4, "source": "request" }
],
"applied": "verified",
"verification": {
"checked": 1,
"matched": 1,
"mismatched": 0,
"dates": [
{ "date": "2026-11-04", "expectedPrice": 180, "bookingPrice": 180, "match": true }
]
},
"booking": { "ok": "" },
"errors": []
}
// 200 — Booking.com acknowledged, but the price on the night did not change.
// Here the rate plan does not price at 6 people, so the amount was declined.
{
"requested": 1,
"occupancy": [
{ "roomId": "123456701", "rateId": "98765", "value": 6, "source": "request" }
],
"applied": "mismatch",
"verification": {
"checked": 1,
"matched": 0,
"mismatched": 1,
"dates": [
{ "date": "2026-11-04", "expectedPrice": 180, "bookingPrice": 0, "match": false }
]
},
"booking": { "ok": "" },
"errors": []
}
// 200 — pushed, acknowledged, not checked. Not a failure; an unknown.
{
"requested": 1,
"occupancy": [
{ "roomId": "123456701", "rateId": "98765", "value": 4, "source": "rate_plan" }
],
"applied": "unverified",
"verification": { "checked": 0, "skipped": true, "reason": "verify=false" },
"booking": { "ok": "" },
"errors": []
}