Change a held time
You are holding 20:00 for a party of four and the guest now wants 21:00. The
API has no call that moves a hold: /v1/holds offers create, read and release,
nothing that edits the time, the date, the party size or the section, and a
conversion that names a different slot from its hold is refused. To change the
time you take a new hold, then release the old one — a swap — with availability
reads between the two.
This comes up most in a package funnel that takes its hold early, while the basket is still being assembled, and then lets the guest change their mind. Taking and releasing a hold is covered in Hold a slot.
Read availability with your own hold excluded
Section titled “Read availability with your own hold excluded”A hold occupies its table for the whole booking duration, so every overlapping slot loses it, and its covers count against the shift cap. A funnel holding 20:00 that then asks what else is free is reading a day with 20:00 missing from it, and if the hold took the last table for that party size the guest is being shown their own held time as unavailable.
excluding answers as if the hold were not there:
curl -G "https://api.useservice.app/v1/availability" \ -H "Authorization: Bearer $SERVICE_API_KEY" \ -d service_date=2026-10-04 \ -d party_size=4 \ -d excluding=hold_AbC3xK9It takes a hold_… id or the resv_… id of a booking, and only ids your key
could already fetch: a value that does not resolve on GET /v1/holds/{id} or
GET /v1/reservations/{id} is a 404, and a value that is neither shape is a
400 naming excluding. It varies the ETag, so a funnel that revalidates gets
the excluded body rather than the one it already had.
GET /v1/availability/months takes it too. The calendar grain is coarser, but
in a small dining room one hold is enough to empty a day — and a calendar that
greys out the date the guest is holding leaves them nowhere to go, because it
sits upstream of the day view they would have used to get back.
Take the new hold before you release the old one
Section titled “Take the new hold before you release the old one”Release-then-create opens a window in which the table is on sale and somebody else can take it. Create-then-release opens none: you hold two tables for one round trip and drop the loser.
POST /v1/holdsfor the new time, taken from the availability read. A time the service does not seat at is refused withstart_time_off_grid, and you are still holding the original.- On success,
DELETE /v1/holds/{old_id}. - On failure, you are still holding the original. Tell the guest that time has
just gone and leave them on the one they have. The one exception: a
hold.releasedyou did not cause means the restaurant released the original from its back office, and then there is nothing left to leave them on.
Do not re-hold on every click
Section titled “Do not re-hold on every click”Writes are limited to one per second, burst 20, and 2,000 a day — see
Rate limits. A guest toggling between six times is
twelve writes for one booking, and a Saturday of that reaches the daily cap on
its own. Hold when the guest commits — on “continue”, not on selection — and
serve everything before that from availability reads with excluding.
The swaps show up in your webhooks as churn
Section titled “The swaps show up in your webhooks as churn”Every swap emits a hold.created and a hold.released. A consumer syncing off
those sees six holds and five releases for a party that booked once, so
reconcile against the reservation rather than against the hold feed.
What an early hold does not buy you
Section titled “What an early hold does not buy you”It protects the time you suggested, if the guest takes it. The moment they move, the hold bought nothing for the time they picked: that table was never held, and the new hold can fail like any other write.