Skip to content

Bookings & reservations

The operator-side booking API drives the live reservation floor: create table and guest-list bookings on a guest’s behalf, move a booking through its lifecycle, seat it on the floor, run the door, and capture or release card-hold deposits. Unless noted, every endpoint requires the operator role (client) and is scoped to venues you can access; most also accept an organiser for events they run. These are staff endpoints - guest self-service booking lives in the widget endpoints.

Method Path Purpose Auth
POST /api/my-venues/:venueId/staff-bookings Create a staff table booking operator
POST /api/my-venues/:venueId/staff-guestlist-bookings Create a staff guest-list booking operator
POST /api/bookings/:id/assign-table Seat a booking on a table operator
POST /api/bookings/:id/auto-assign Auto-pick and seat a table operator
POST /api/bookings/:id/unassign-table Remove the table assignment operator
PATCH /api/bookings/:id/details Edit party size, tags, comments operator
POST /api/bookings/:id/lifecycle Set paid / in-use / check-in flags operator
POST /api/bookings/:id/lock Lock or unlock a table assignment operator
POST /api/bookings/:id/duration Override the booking duration operator
POST /api/bookings/:id/close Close out a seated booking operator
PATCH /api/bookings/:id/status Set booking status operator
POST /api/bookings/:id/approve Approve a pending booking operator
POST /api/bookings/:id/reject Reject a booking operator
POST /api/bookings/:id/unreject Undo a rejection (→ pending) operator
POST /api/bookings/:id/staff-cancel Cancel a booking as staff operator
POST /api/check-in Check a guest in with a QR code operator
POST /api/door-reject Reject a guest at the door operator
POST /api/bookings/:id/hold/capture Capture a card hold (full/partial) operator
POST /api/bookings/:id/hold/release Release a card hold operator
POST /api/bookings/:id/hold/refund Refund a captured deposit operator
POST /api/bookings/:id/hold/request Email the guest a deposit link operator
POST /api/bookings/:id/hold/intent Create a MOTO card-entry hold operator
POST /api/bookings/:id/deposit/capture Capture every live hold on a booking, up to an amount operator
POST /api/bookings/:id/deposit/topup Ask the guest to pay the difference as a top-up operator
POST /api/bookings/:id/deposit/legs/:legId/:action Capture, release, refund, cancel or limit one top-up operator
POST /api/bookings/:id/hold/limit Reduce a live hold’s capture limit operator
POST /api/bookings/:id/deposit/reset Cancel a stuck deposit or unpaid payment link operator
GET /api/bookings/:id Read one booking (detail + QR) session
GET /api/bookings/:id/history Read a booking’s audit trail operator
GET /api/bookings/:id/payment-refs Payment references and deposit history operator
POST /api/bookings/:id/discount Apply or clear a staff discount operator
POST /api/bookings/:id/reassign-guest Attach a different guest to a booking operator
POST /api/bookings/:id/resend-confirmation Re-email the booking confirmation operator
POST /api/bookings/:id/swap-table Swap tables between two bookings operator
GET /api/bookings/:id/preorder/options Items available to add to a booking operator
POST /api/bookings/:id/preorder/items Add staff pre-order items operator
POST /api/bookings/:id/preorder/remove Remove a staff-added pre-order item operator
GET /api/bookings/:id/preorder/request Whether a pre-order request can be sent operator
POST /api/bookings/:id/preorder/request Send or resend the pre-order request operator
GET /api/my-venues/:venueId/preorders Pre-order items across reservations operator
GET /api/my-reservations/calendar Floor calendar across venues operator
GET /api/my-venues/:venueId/reservations List venue reservations for a date operator
POST /api/my-venues/:venueId/reservations Create a venue reservation operator
PUT /api/my-venues/:venueId/reservations/:resId Update a venue reservation operator
DELETE /api/my-venues/:venueId/reservations/:resId Delete a venue reservation operator
DELETE /api/my-venues/:venueId/reservations/:resId/no-show Undo a no-show mark operator

Book a table on a guest’s behalf. Requires a user_id (see Guests to find or create one) and a table_id.

Terminal window
curl -X POST "https://thesidedoor.co/api/my-venues/VENUE_ID/staff-bookings" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"user_id": "usr_abc",
"table_id": "tbl_12",
"reservation_date": "2026-07-17",
"reservation_time": "20:00",
"party_size": 4,
"duration_mins": 120,
"reservation_tags": ["birthday"],
"notes": "Window table if possible"
}'
{ "success": true, "booking_id": "bkg_9a1" }

table_id also accepts "auto" to pick the best free table at save time, or "none" to book the guest without a table at all. A "none" booking is flagged so it’s never picked up by auto-assignment; seat it later when you’re ready.

Add a guest to a list for an access rule. time defaults to the rule’s start time when omitted.

Terminal window
curl -X POST "https://thesidedoor.co/api/my-venues/VENUE_ID/staff-guestlist-bookings" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"user_id": "usr_abc",
"access_rule_id": "rul_7",
"booking_date": "2026-07-17",
"party_size": 2,
"reservation_tags": ["vip"]
}'
{ "success": true, "booking_id": "bkg_9a2" }

Assign a specific table, or let Sidedoor auto-pick one. new_time moves the booking as you drag it; allow_blocked overrides a blocked table.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/assign-table" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"table_id":"tbl_12","new_time":"20:30"}'
{ "success": true, "table_id": "tbl_12", "booking_time": "20:30" }

POST /api/bookings/:id/auto-assign takes no body and returns the picked table.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/auto-assign" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN"
{ "success": true, "table_id": "tbl_08" }

POST /api/bookings/:id/unassign-table (no body) clears the assignment.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/unassign-table" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN"
{ "success": true }

Update the party size, reservation tags or comments. Send at least one field; changing party_size also syncs the guest count.

Terminal window
curl -X PATCH "https://thesidedoor.co/api/bookings/BOOKING_ID/details" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"party_size":6,"reservation_tags":["birthday","allergy"],"comments":"Nut allergy"}'
{ "success": true }

POST /api/bookings/:id/discount applies (or replaces) a staff discount on a booking - kind is amount (pence) or percent, with a value and who requested_by it (required, for the audit trail); an optional note. Send { "clear": true } to remove it instead.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/discount" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"kind":"percent","value":10,"requested_by":"Manager on duty","note":"Service recovery"}'
{ "success": true, "discount": { "kind": "percent", "value": 10, "requested_by": "Manager on duty" }, "reservation_tags": [] }

POST /api/bookings/:id/reassign-guest attaches a different guest to a booking - pass a user_id for one of your own guests, or guest_name (with an optional guest_phone) for a walk-in with no account.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/reassign-guest" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"user_id":"usr_def"}'
{ "success": true }

POST /api/bookings/:id/resend-confirmation re-sends the booking confirmation email. It only works on a confirmed, upcoming booking - once a booking is checked in, closed, cancelled, marked a no-show or its start time has passed, it returns a 409.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/resend-confirmation" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN"
{ "success": true, "email": "sam@example.com" }

POST /api/bookings/:id/swap-table swaps the table assignments of two seated, same-time table bookings in one move - pass the other_id of the booking to swap with. Neither booking can be part of a table combination, and both must already be seated at the same start time.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/swap-table" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"other_id":"bkg_other"}'
{ "success": true }

GET /api/bookings/:id/payment-refs returns the booking’s payment references and deposit history - the Stripe reference for each payment plus the history of what’s happened to it.

Terminal window
curl "https://thesidedoor.co/api/bookings/BOOKING_ID/payment-refs" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN"
{
"refs": [{ "id": "pi_123", "label": "Deposit", "status": "captured" }],
"history": [{ "at": "2026-06-20T18:00:00Z", "label": "Deposit captured" }],
"currency": "GBP",
"timezone": "Europe/London"
}

Toggle the front-of-house flags on a seated booking: paid (with optional paid_amount in pence), in_use, and check_in.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/lifecycle" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"paid":true,"paid_amount":12000,"in_use":true}'
{ "success": true }

Lock a table so auto-assign won’t move it (locked: true/false/null to clear the override), override the duration in minutes, or close out a booking.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/lock" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"locked":true}'
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/duration" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"duration_mins":150}'
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/close" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"closed_at_wallclock":"2026-07-17T23:15:00"}'
{ "success": true, "locked": 1 }

Set a booking’s status directly to one of pending, approved, rejected, cancelled or checked_in. reason is used when rejecting. Terminal states (checked_in, cancelled) return 409.

Terminal window
curl -X PATCH "https://thesidedoor.co/api/bookings/BOOKING_ID/status" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"status":"approved"}'
{ "success": true, "status": "approved" }

Dedicated verbs for the approval queue. approve and unreject (undo a rejection → pending) take no body; reject takes an optional reason; staff-cancel cancels the booking (returns 409 once checked in).

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/approve" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN"
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/reject" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"reason":"Fully booked"}'
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/staff-cancel" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN"
{
"success": true,
"booking": {
"id": "bkg_9a1",
"status": "approved",
"approved_by_name": "Front Desk",
"approved_at": "2026-07-15T09:12:00Z"
}
}

On the door, check a guest in against their QR code, or reject them. The reason on door-reject must be one of at_capacity, barred, attitude, dresswear or unspecified.

Terminal window
curl -X POST "https://thesidedoor.co/api/check-in" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"booking_id":"BOOKING_ID","qr_code":"eyJ2IjoxLCJi..."}'
{
"success": true,
"booking": { "id": "bkg_9a1", "status": "checked_in" },
"checked_in_at": "2026-07-17T21:04:00Z",
"checked_in_by_name": "Door"
}

To reject at the door:

Terminal window
curl -X POST "https://thesidedoor.co/api/door-reject" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"booking_id":"BOOKING_ID","reason":"dresswear"}'
{
"success": true,
"reason": "Dress code",
"refunded": false,
"door_rejected_by_name": "Door",
"door_rejected_at": "2026-07-17T21:06:00Z"
}

When a booking policy takes a card-hold deposit, staff can capture it (in full or partially), release an uncaptured hold, refund one that has already been captured, email the guest a deposit link, or take a card in person over the phone (MOTO).

Omit amount_pence to capture the full authorised amount, or pass a smaller value for a partial capture.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/hold/capture" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"amount_pence":5000}'
{ "success": true, "status": "captured", "amount_pence": 5000 }

POST /api/bookings/:id/hold/release (no body) voids the authorisation.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/hold/release" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN"
{ "success": true, "status": "released" }

POST /api/bookings/:id/hold/refund (no body) refunds a deposit that has already been captured, sending the money back to the guest’s card. This is the only way to return a captured deposit. It is valid only once the deposit has been captured (via hold/capture, or a deposit charged upfront at booking); a live, uncaptured hold returns 409 and must go through hold/release instead.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/hold/refund" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN"
{ "success": true, "status": "refunded", "amount_pence": 5000 }

Email the guest a deposit link. The link is a durable Sidedoor-hosted /pay/:id URL (it mints a fresh Checkout session when the guest clicks), not a raw checkout.stripe.com address, so don’t match on the Stripe domain. amount_pence is required (min 50); set notify with an email to send it.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/hold/request" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"amount_pence":5000,"description":"Table deposit","notify":true,"email":"guest@example.com"}'
{
"success": true,
"checkout_url": "https://thesidedoor.co/pay/bkg_9a1",
"amount_pence": 5000,
"emailed": true
}

POST /api/bookings/:id/hold/intent starts a manual-capture card hold for keying a card at the desk. It returns a Stripe client_secret and publishable_key alongside the intent_id. The card is never sent to Sidedoor: your desk UI collects it with Stripe.js (for example stripe.confirmCardPayment using the client_secret, with Stripe.js initialised from the publishable_key), which confirms the PaymentIntent directly with Stripe and puts the hold in place. The intent_id alone can’t complete the card entry - it’s there so you can track the hold. Once confirmed, capture, release or refund it with the endpoints above.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/hold/intent" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"amount_pence":5000}'
{
"client_secret": "pi_..._secret_...",
"intent_id": "pi_...",
"publishable_key": "pk_live_...",
"amount_pence": 5000
}

POST /api/bookings/:id/deposit/capture captures every live hold on a booking in one go - the original deposit plus any held top-ups - up to an amount_pence you choose (omit it to take everything). The original is captured first, then each top-up, oldest first; anything the amount doesn’t reach is released rather than left dangling.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/deposit/capture" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
{ "success": true, "captured_pence": 9000 }

POST /api/bookings/:id/hold/limit is “reduce deposit”: it caps how much of a live, uncaptured hold a later capture can take, without releasing or re-holding anything. Send the most that should ever be captured as amount_pence (at or above the full held amount clears the limit again), and an optional reason.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/hold/limit" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"amount_pence":2000,"reason":"Party size reduced"}'
{ "success": true, "capture_limit_pence": 2000, "held_pence": 4000 }

When a booking grows, POST /api/bookings/:id/deposit/topup asks the guest to pay just the difference as a separate payment, kept apart from what they’ve already paid or held. Send the extra amount_pence (minimum 50); notify and email control whether and where the guest is emailed a link, and description is an optional note. To resend an existing top-up’s link (or re-request one whose hold lapsed), pass its leg_id instead of a fresh amount.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/deposit/topup" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"amount_pence":1500,"notify":true,"email":"sam@example.com"}'
{ "success": true, "checkout_url": "https://thesidedoor.co/pay/BOOKING_ID?leg=leg_1", "leg_id": "leg_1", "amount_pence": 1500, "total_pence": 5500, "emailed": true, "notified": true }

Each top-up is its own payment “leg”. POST /api/bookings/:id/deposit/legs/:legId/:action runs an action on a single leg, where :action is one of:

Action Applies to Body
capture A held top-up amount_pence (optional - omit to take all that’s held)
release A held top-up none
refund A charged top-up amount_pence (optional - omit to refund all that’s left)
cancel An unpaid top-up link none
limit A held top-up amount_pence (required - same “reduce” behaviour as hold/limit)
Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/deposit/legs/leg_1/capture" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
{ "success": true, "status": "captured", "amount_pence": 1500 }

POST /api/bookings/:id/deposit/reset clears a deposit that’s stuck with no funds actually held - an expired advance-hold request, an abandoned card step, or an unpaid payment link - so the Deposit tab shows the request form again. It refuses with a 409 if Stripe shows any funds held or taken; use capture, release or refund for those. Takes an optional reason.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/deposit/reset" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"reason":"Guest abandoned the card step"}'
{ "success": true, "previous_amount_pence": 4000 }

GET /api/bookings/:id returns the full booking with its guest, table, QR code and edit/cancel flags. Any authenticated user may call it, gated by role, venue access or ownership.

Terminal window
curl "https://thesidedoor.co/api/bookings/BOOKING_ID" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN"
{
"booking": {
"id": "bkg_9a1",
"status": "approved",
"party_size": 4,
"table_number": "12",
"seating_area_name": "Terrace",
"venue_name": "The Attic",
"duration_mins": 120
},
"user_name": "Sam Lee",
"user_phone": "+44...",
"membership_tier": "black",
"qr_code": "eyJ2IjoxLCJi...",
"qr_expires_in_ms": 60000,
"is_editable": true
}

GET /api/bookings/:id/history returns the chronological audit trail.

Terminal window
curl "https://thesidedoor.co/api/bookings/BOOKING_ID/history" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN"
{
"events": [
{ "at": "2026-07-15T09:00:00Z", "type": "created", "actor": "Front Desk", "details": null },
{ "at": "2026-07-15T09:12:00Z", "type": "approved", "actor": "Front Desk", "details": null },
{ "at": "2026-07-17T21:04:00Z", "type": "checked_in", "actor": "Door", "details": null }
]
}

Staff can add pre-order and add-on items to a booking directly, or send the guest a link to add their own - see Sending a pre-order request for how this reads in the portal.

GET /api/bookings/:id/preorder/options returns the bundles and items available to add, restricted to what the booking’s access profile offers (restricted: true when it is). POST /api/bookings/:id/preorder/items adds a selections array of items (re-priced server-side); they’re added as unpaid, staff-added lines. Remove one with POST /api/bookings/:id/preorder/remove (item_id, and variant_options if the item has variants) - only staff-added lines can be removed this way; an item the guest paid for at checkout can’t be.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/preorder/items" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"selections":[{"item_id":"itm_1","qty":2}]}'
{ "success": true, "added": [{ "item_id": "itm_1", "qty": 2, "name": "Bottle of Prosecco" }], "bundle_selections": [] }

GET /api/bookings/:id/preorder/request reports whether a request can be sent right now (ok, with reason when it can’t - the booking’s cancelled, past its pre-order cutoff, or its access profile offers nothing to pre-order) and the guest_email it would go to; sent is true once a request has already gone out, in which case sending again is a resend. POST /api/bookings/:id/preorder/request sends (or resends) it over the venue’s deposit-request channels - email, app push and SMS; pass email to override the guest’s email for this send.

Terminal window
curl -X POST "https://thesidedoor.co/api/bookings/BOOKING_ID/preorder/request" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
{ "success": true, "link": "https://thesidedoor.co/preorder-request/TOKEN", "resend": false, "emailed": true }

GET /api/my-venues/:venueId/preorders lists every pre-order line item across a venue’s reservations - one row per item, not per booking. Filter with q (search), from/to (date range), window (past/upcoming), status, deposit (yes/no), paid (paid/held/pay_at_venue/unpaid) and page with limit/offset. The response wraps the page in data alongside total, has_more, a summary and per-status totals; a large result is flagged truncated so you know to narrow the date range.

Terminal window
curl "https://thesidedoor.co/api/my-venues/VENUE_ID/preorders?window=upcoming&paid=unpaid" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN"
{
"data": [{ "booking_id": "bkg_456", "item_id": "itm_1", "name": "Bottle of Prosecco", "qty": 2, "paid": "unpaid" }],
"total": 1,
"has_more": false,
"truncated": false
}

GET /api/my-reservations/calendar returns the whole floor - venues, areas, tables, reservations, bookings, orphans and blockouts - for a date range. It is ETag-cached; send If-None-Match for a 304.

Terminal window
curl "https://thesidedoor.co/api/my-reservations/calendar?from=2026-07-17&to=2026-07-17&venue=VENUE_ID" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN"
{
"venues": [{ "id": "ven_123", "name": "The Attic", "grid_colors": {} }],
"areas": [{ "id": "area_1", "venue_id": "ven_123", "name": "Terrace" }],
"tables": [{ "id": "tbl_12", "venue_id": "ven_123", "area_id": "area_1", "table_number": "12", "capacity": 4 }],
"reservations": [
{ "id": "res_1", "source": "venue_reservation", "table_id": "tbl_12", "guest_name": "Sam Lee", "party_size": 4, "start_time": "20:00", "end_time": "22:00", "status": "confirmed" }
],
"orphans": [],
"blockouts": []
}

Lightweight floor reservations for named walk-in and phone guests, scoped to a venue.

Terminal window
curl "https://thesidedoor.co/api/my-venues/VENUE_ID/reservations?date=2026-07-17" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN"
{
"data": [
{ "id": "res_1", "table_id": "tbl_12", "table_number": "12", "guest_name": "Sam Lee", "party_size": 4, "reservation_time": "20:00", "status": "confirmed" }
]
}

table_id, guest_name, reservation_date and reservation_time are required.

Terminal window
curl -X POST "https://thesidedoor.co/api/my-venues/VENUE_ID/reservations" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"table_id": "tbl_12",
"guest_name": "Sam Lee",
"guest_phone": "+44...",
"party_size": 4,
"reservation_date": "2026-07-17",
"reservation_time": "20:00",
"duration_mins": 120,
"reservation_tags": ["anniversary"],
"notes": "Quiet corner"
}'
{ "success": true, "id": "res_1" }

PUT accepts any subset of the create fields (plus status); DELETE takes no body.

Terminal window
curl -X PUT "https://thesidedoor.co/api/my-venues/VENUE_ID/reservations/RES_ID" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"party_size":6,"status":"confirmed"}'
curl -X DELETE "https://thesidedoor.co/api/my-venues/VENUE_ID/reservations/RES_ID" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN"
{ "success": true }

DELETE /api/my-venues/:venueId/reservations/:resId/no-show reverses a no-show mark (whether set by staff or Sidedoor’s own sweep) back to approved, restoring its original duration. It’s rejected with a 409 if that would now clash with another reservation on the same table - move the conflicting booking first.

Terminal window
curl -X DELETE "https://thesidedoor.co/api/my-venues/VENUE_ID/reservations/RES_ID/no-show" \
-H "Authorization: Bearer $SIDEDOOR_TOKEN"
{ "success": true }