Skip to content
RReservory
ProductIndustriesPricingvs ROLLERDesign partners
Sign inStart free
Product↗Industries↗Pricing↗vs ROLLER↗Design partners↗About Reservory↗Sign in↗
Getting StartedAPI ReferenceWebhooks

On this page

  1. Auth at a glance
  2. Data (API key, v1)
  3. Booking
  4. Payments
  5. Webhooks (outbound)
  6. Webhook signatures
On this page
  1. Auth at a glance
  2. Data (API key, v1)
  3. Booking
  4. Payments
  5. Webhooks (outbound)
  6. Webhook signatures

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; requireOperator enforces the role floor server-side

Data (API key, v1)

GET/api/v1/bookingsapi key · read

List 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.

200 — { data: [{ id, reference, status, product_id, starts_at, customer, total_amount_cents, currency, ... }], next_cursor }
400 — invalid_query

limit 1–100 (default 50). Money is integer cents with currency; times are ISO 8601 UTC.

GET/api/v1/bookings/[id]api key · read

One booking by UUID or booking reference, in the list shape.

404 — booking_not_found (including another account's booking)
GET/api/v1/customersapi key · read

List customers. Filters: email (exact), updated_since. Keyset paged like bookings.

GET/api/v1/productsapi key · read

List products, including drafts and archived ones. Keyset paged like bookings.

GET/api/v1/availability?product_id=&from=&to=api key · read

Bookable 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

GET/api/widget/experience?tenant=&experience=anon

Widget 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.

200 — { tenant_id, effective_party_size, experience, slots: [{ id, starts_at, ends_at, seats_remaining, price_cents, pricing_multiplier_bps }] }
404 — tenant_unavailable | experience_not_found | venue_unavailable
400 — missing_params | invalid_party_size
503 — product_configuration_unavailable | slots_lookup_failed | availability_unavailable
POST/api/bookings/holdanon

Acquire a 10-minute soft hold on N seats. Rate-limited 10/min/IP.

Body
{ slot_id, experience_id, seats }
200 — { hold_id, slot_id, expires_at, seats_remaining }
409 — hold_unavailable (reason: insufficient_capacity | already_held | ...)

Supports Idempotency-Key header. CORS-enabled.

POST/api/bookingsanon

Convert a hold into a booking. Returns a signed booking_token for the customer payment-intent route.

Body
{ 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? }
201 — { booking_id, booking_token, waiver_url, payment_complete, promo_discount_cents, gift_card_applied_cents }
410 — hold_expired
409 — capacity_exceeded | slot_already_booked

Persist the key before sending. Completed identical requests replay; uncertain execution can require reconciliation. Never start another booking to bypass uncertainty.

GET/api/forms/checkout/[experienceId]anon

Read current published forms and session_token. Server/same-origin only; upload fields use hosted checkout.

GET/api/embed/bookings/[id]signed token

Read canonical booking status with X-Booking-Token. Only confirmed means booking completion.

POST/api/bookings/[id]/canceloperator manager+

Cancel a held / payment-pending / confirmed booking. Does NOT refund.

200 — { ok: true, id }
POST/api/bookings/[id]/check-inoperator staff+

Stamp checked_in_at + checked_in_by_user_id. Idempotent.

200 — { checked_in_at } or { already_checked_in: true, checked_in_at }

Payments

POST/api/embed/bookings/[id]/payment-intentsigned token

Customer-facing PI creation. Requires X-Booking-Token (HMAC issued at booking-create).

200 — { clientSecret, paymentIntentId, publishableKey }
202 — Pending operation; preserve the same key and check canonical booking status.
401 — invalid_booking_token
503 — stripe_not_configured | connected_account_not_ready

Webhooks (outbound)

POST/api/webhooks/endpointsadmin api key · write

Create a subscription (REST hook). Signing secret returned once. Also callable from an admin dashboard session.

Body
{ url, events:[booking.created, booking.confirmed, booking.cancelled, refund.created, waiver.signed] }
DELETE/api/webhooks/endpoints/[id]admin api key · write

Delete 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.

RReservory

Booking, payments, point of sale and waivers for attractions venues.

PRODUCT

  • Checkout
  • Point of sale
  • Waivers
  • Owner app
  • Integrations
  • Pricing

INDUSTRIES

  • Escape rooms
  • Axe throwing
  • Mini golf
  • Trampoline parks
  • All industries

RESOURCES

  • Live demo
  • Documentation
  • API reference
  • Webhooks

COMPANY

  • About
  • Design partners
  • Changelog
  • Careers
  • Security
  • Talk to us
© 2026 Reservory · Privacy · Terms · Security · Responsible disclosure · hello@reservory.com