The visitor calls us from the widget
POST/api/widget/call
PUBLIC endpoint (anonymous visitor, no staff auth). The visitor's SDP offer is the ONLY thing they send: who they are, which conversation this is and which tenant they belong to all come from the verified session token.
Media is answered BEFORE anybody's phone rings — on this channel there is no platform in between whose accept we are waiting for — so the recording notice, the out-of-hours sentence and the queue's hold music reach the visitor while the team is still being rung. The call then walks the SAME five inbound steps a WhatsApp call walks (redial defence, switchboard, the assistant's turn, routing, queue + pushes).
Refusals carry a NAMED code so the widget can tell "this business does
not take calls" (hide the button) from "something went wrong" (say so,
let them retry): voice_disabled · no_conversation · line_not_ready
· call_in_progress · announcement_unavailable · media_failed.
Request
Responses
- 201
- 403
- 404
- 409
- 422
- 502
Media is up and the team is being rung.
The tenant has not switched widget calling on (voice_disabled).
No conversation is bound to this session.
The call cannot start yet — a named code says which: the widget channel is not live, a call is already in flight on this thread, or the recording notice could not be produced under a required policy.
The request failed validation.
The media bridge refused (media_failed).