Developers / REST API
Reservory REST API
Supported public REST surface. All responses are JSON. CORS-enabled where indicated (anon endpoints). Mutating POSTs accept an Idempotency-Key header for safe client retries.
Tenant API keys read data through /api/v1 (read scope), cancel and check in bookings (write scope), and manage webhook subscriptions (admin role, write scope). Cancellation never refunds. Refunds and other administrative actions require authorized dashboard sessions and are outside this API contract.
Machine-readable spec: /api/openapi.json (OpenAPI 3.1, covers the public booking + payment surface). Import into Postman, Stoplight, or any SDK generator.
Auth at a glance
- anon — no auth; CORS-open; rate-limited where relevant
- signed token — HMAC token issued at booking-create or waiver-dispatch; passed as a header (
X-Booking-Token) or URL segment - api key —
Authorization: Bearer rsv_*; read scope for GET, write scope for other methods, plus the key role (staff, manager or admin). Pro/Enterprise only - operator staff+/manager+/admin+ — Supabase JWT bearer;
requireOperatorenforces the role floor server-side
Data (API key, v1)
/api/v1/bookingsapi key · readList bookings. Filters: starts_from, starts_to (session start), status (comma list), updated_since. Keyset paged on (updated_at, id): pass next_cursor as cursor until it is null.
limit 1–100 (default 50). Money is integer cents with currency; times are ISO 8601 UTC.
/api/v1/bookings/[id]api key · readOne booking by UUID or booking reference, in the list shape.
/api/v1/customersapi key · readList customers. Filters: email (exact), updated_since. Keyset paged like bookings.
/api/v1/productsapi key · readList products, including drafts and archived ones. Keyset paged like bookings.
/api/v1/availability?product_id=&from=&to=api key · readBookable slots the widget would offer for one product between two venue-local dates (at most 31 days). Optional party_size. Up to 40 per page with next_cursor.
Booking
/api/widget/experience?tenant=&experience=anonWidget bootstrap. Returns experience metadata and up to 40 available slots, filtered by capacity and business hours. Optional party_size must be an integer from 1 to 200; effective_party_size is at least the product minimum.
/api/bookings/holdanonAcquire a 10-minute soft hold on N seats. Rate-limited 10/min/IP.
{ slot_id, experience_id, seats }Supports Idempotency-Key header. CORS-enabled.
/api/bookingsanonConvert a hold into a booking. Returns a signed booking_token for the customer payment-intent route.
{ hold_id, slot_id, experience_id, venue_id, customer:{email,first_name,last_name?,phone?}, guest_count, notes?, tickets?, form_responses?, form_session_token?, promo_code?, gift_card_code?, addons? }Persist the key before sending. Completed identical requests replay; uncertain execution can require reconciliation. Never start another booking to bypass uncertainty.
/api/forms/checkout/[experienceId]anonRead current published forms and session_token. Server/same-origin only; upload fields use hosted checkout.
/api/embed/bookings/[id]signed tokenRead canonical booking status with X-Booking-Token. Only confirmed means booking completion.
/api/bookings/[id]/canceloperator manager+Cancel a held / payment-pending / confirmed booking. Does NOT refund.
/api/bookings/[id]/check-inoperator staff+Stamp checked_in_at + checked_in_by_user_id. Idempotent.
Payments
/api/embed/bookings/[id]/payment-intentsigned tokenCustomer-facing PI creation. Requires X-Booking-Token (HMAC issued at booking-create).
Webhooks (outbound)
/api/webhooks/endpointsadmin api key · writeCreate a subscription (REST hook). Signing secret returned once. Also callable from an admin dashboard session.
{ url, events:[booking.created, booking.confirmed, booking.cancelled, refund.created, waiver.signed] }/api/webhooks/endpoints/[id]admin api key · writeDelete a subscription (REST-hook unsubscribe). Idempotent; pending deliveries dropped.
Webhook signatures
Outbound webhook deliveries include X-Reservory-Timestamp and X-Reservory-Signature: v1,<hex>. The signature is HMAC-SHA256 of `${timestamp}.${rawBody}` with your endpoint's signing secret. Reject deliveries older than 5 minutes to mitigate replay attacks.