Cancel by token
POST /api/public/bookings/cancel-by-token
Content-Type: application/json
{ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." }The token is a JWT signed at booking-create time with claims:
bookingIdagencyIdexp— slot start + 60s (past that point the customer should call the business)
Verified server-side; mismatched signature / expired → 400.
Response
Success:
{ "ok": true, "alreadyCancelled": false, "startAt": "2026-06-01T03:30:00.000Z" }Already cancelled (idempotent):
{ "ok": true, "alreadyCancelled": true, "startAt": "2026-06-01T03:30:00.000Z" }Terminal status (NO_SHOW / COMPLETED): 409
Invalid / expired: 400 with code: "INVALID" | "EXPIRED".
Why POST not DELETE
Customer reaches this via a link they click in the confirmation screen. POST avoids the GET-link-prefetch problem where an over-eager mail client would auto-cancel the booking on link hover.
The token lives in the body (not URL query) for the same reason.
Idempotency
Calling cancel twice on the same booking returns success both times. The first one deletes the Google event + flips status; the second is a no-op.
Last updated on