Guest self-service

Answer the venue's intake form

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

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.

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.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X PUT "https://example.com/api/book/string/manage/string" \  -H "Content-Type: application/json" \  -d '{    "answers": {      "property1": "string",      "property2": "string"    }  }'
{  "ok": true}