Guest self-service

Cancel a booking

delete/api/book/{slug}/manage/{token}

Sets status to cancelled rather than deleting, so the venue keeps the history and the slot or table is released by exactly the rules a staff cancellation uses. Compare-and-set on the current status.

Path Parameters

slug*string

The organization's public booking slug, i.e. the {slug} in /{slug}. Only orgs with status active resolve; anything else is a 404.

token*string

The booking's manage token.

Response Body

application/json

application/json

application/json

application/json

application/json

curl -X DELETE "https://example.com/api/book/string/manage/string"
{  "ok": true}

Move a booking to another time PATCH

Guest-initiated reschedule, for both engines. Which engine is in play is resolved from the org's `business_type` inside `loadByToken`, so the caller does not choose; this is the one endpoint that serves both and the only one where that is correct, because a manage link is a link to *a booking*, not to a product. Only the time changes. Same service, same staff member, same party size; that is what keeps a guest reschedule auto-approvable without staff review. The new time must satisfy the org's notice period too, or a guest could sidestep the cutoff by moving to a slot an hour from now. The slot is re-derived server-side and the update is a compare-and-set on the current status, so a booking staff cancelled mid-flow is not resurrected.

Answer the venue's intake form PUT

The guest fills in whatever questions the org defined for this booking (migration 0024). Serves both engines for the same reason PATCH does; the token is a link to *a booking*, and which engine that booking belongs to is resolved from the org's `business_type` inside `loadByToken`. PUT rather than POST because there is exactly one response per booking, enforced by a partial unique index per subject id: a guest reopening their link EDITS their answers rather than stacking a second submission staff would have to reconcile. The form is re-resolved server-side rather than taken from the body: the page may have been rendered days ago, and the org may have switched forms or deactivated one since. A service-specific form wins over the org-wide one, and only `active` forms are served. Answers are validated against that form; required questions present, dropdown answers within their `options`, lengths capped, and `fields_snapshot` is rewritten from it on every save, so staff always read these answers against the questions that were actually on screen. Deliberately NOT gated on the org's guest-self-service policy, unlike PATCH and DELETE, and for the same reason POST is not: an org that switched off guest rescheduling still asked these questions, and a notice period is backwards here; the hour before a visit is exactly when someone remembers their allergy.