Public queue self-booking
Every queue you publish gets a hosted booking page at a public URL — no account, no sign-in:Tenant setup — expose a queue as bookable
The surface is off until you opt in per organization. Flip it on with a settings write:cURL
#rrggbb colours, and caps the copy lengths):
cURL
https://orbit.devotel.io/book/{ tenantId from GET /settings/general }/{ the queue id }.
Turn it back off by writing "enabled": false — the booking page renders the 404 and the booking POST answers 422 with the same shape an unknown tenant gets, so nothing picks apart your inventory (an attacker can’t tell a queue that never existed from a queue you closed).
Publish the queue’s bookable window
The page publishes slots only for queues with a schedule. Two levels:- Per-queue hours —
businessHourson the queue itself. Set or override it viaPUT /api/v1/voice/queues/{id}with thebusinessHoursfield (IANA timezone + day windows). A queue without abusinessHoursfalls back to the org default, which you set viaPUT /api/v1/organization/business-hours. - A queue with neither has no published schedule, the availability endpoint reports
reason: "no_schedule_configured"with an empty slot list, and the booking POST returns 422NO_BOOKABLE_SCHEDULE.
cURL
slot_minutes (5–240, default 30) and lead_minutes (minimum notice before a slot, 0–20160, default 60) — the page and API accept both as query overrides, so a booking link can ask for 45-minute slots with 2-hour notice without changing the queue configuration.
Booking lifecycle
Every booking runs the same four steps:- Availability.
GET /api/v1/public/queues/{tenantId}/{queueId}/availability(or the booking page itself, which calls this) enumerates the queue’s business-hours window into concrete slots and subtracts the slots already holding a booking, so two customers can’t take the same slot. - Book.
POST /api/v1/public/queues/{tenantId}/{queueId}/appointmentswrites one scheduled callback row with the caller’sphoneand chosenslot_start. - Dispatch. At the slot start, the queue’s callback dispatcher dials the caller. The dial respects the queue’s callback retry/attempt settings, and the row the booking wrote is the same shape as a callback your agents queue from the dashboard.
- Cancel or reschedule. The caller receives a tracking link (
GET /api/v1/public/callbacks/<token>) in the “your callback is on its way” message — a signed HMAC envelope that carries the callback id, never a tenant id or queue id the caller could tamper with. Status, one-tap cancel, and reschedule all run that same token (see Callbacks and scheduling). The booking’s consent record stays in your audit log either way.
cURL
409 SLOT_ALREADY_BOOKED (the caller picks another); a queue that published no schedule answers 422 NO_BOOKABLE_SCHEDULE; anything that can’t identify the tenant or that hasn’t opted in answers 422 INVALID_TENANT.
Integration — get the link into a caller’s hands
- SMS deep link. Send the booking URL in the message. Append
?phone=<E.164>and the phone field arrives pre-filled, so the caller taps a slot with nothing to type:https://orbit.devotel.io/book/<tenantId>/<queueId>?phone=+15551234567. - Email footer / ticket link. Drop the URL into signature blocks or the “can’t wait?” line of a support reply; the page renders the branding and copy you configured.
- QR code (for in-store / printed collateral). Point the QR at the URL; any phone camera can open it.
- IVR hand-off — pair the booking cue with the existing press-1 virtual callback flow: when the queue offers a callback in-queue, play the booking URL instead and send it by SMS to the caller, so the caller who wants a scheduled slot picks it off the page rather than waiting to be dialled.
Ops
- No existence signal. A queue that is closed or unknown returns
{ "enabled": false }on the availability GET and422 INVALID_TENANTon the booking POST — the same body an unknown tenant gets either way. Never verify “is this queue enabled?” from a public reader; verify inside your own systems. - Rate limiting. Every public call to the surface sits under the per-IP public surface limit. If you embed booking into your own agent or routing flow, pick the slot client-side first and then forward the booking POST so a half-finished journey never burns the public budget.
- SLA and audit inherit the queue. The queue’s SLA target, occupancy, and health metrics read the booking rows the dispatcher dialled, so the booking surface and the manual callback queue share the wallboard you already run. The booking audit row keeps the caller’s phone masked (the raw number lives on the callback row for dispatch only), and the booking remains the caller’s consent to a callback at the chosen slot.
Related
- Callbacks and scheduling — the tracking token’s cancel/reschedule surface and the scheduled callback pipeline this page writes into.
- Queue SLA forecast-callback runbook — the queue-level SLA objective the booked callbacks share.
- Voice queues — create, staff, and tune the queue before you publish it.