Skip to main content
A web call is a voice call between a browser and an agent. It’s a real call: it shows up in GET /v1/calls with channel: "web", uses minutes, is recorded and analysed like a phone call, and fires the same webhooks.
Just want a talk button on your website? The web chat widget already includes voice, with one script tag and no code. Use the API when you want voice inside your own app or page.

How it fits together

Your API key never leaves your server. The browser gets a grant: a short-lived, single-use credential that can only connect this one call, and only from the website you named.

1. Create the session on your server

Set allowed_origin to the exact origin of the page that will connect, like https://your.site. Only that page can use the grant.
The answer is 202 Accepted, with the usual call fields plus: variables, metadata, client_ref and test_mode work as they do for phone calls.

2. Connect from the browser

The web client opens the microphone, negotiates WebRTC, plays the agent’s voice and gives you live events. It never sees an API key.
call.state moves through requesting_microphone, connecting, connected, reconnecting, ending and ended (or failed). WebCallError.code says what went wrong: permission_denied, microphone_missing, grant_expired, capacity_exceeded, signaling_timeout, connection_lost and more.

Errors and limits

Good to know

  • Audio quality. The agent’s voice is sent at phone quality (8 kHz) by default, so it sounds like a real call. Set audio.wideband: true on the agent for 16 kHz.
  • One session, one call. If negotiation fails, create a new session.
  • Limits. Web calls count toward the workspace’s concurrent-call limit, use minutes like phone calls, and end at the agent’s call.max_duration_sec.
  • Teammates can listen in and take over web calls from the dashboard’s live console.
  • Server relay still works. POST /v1/web-call-sessions/{call_id}/offer (with your API key and X-Webcall-Grant) remains for setups that relay the offer through their own server.