Errors and troubleshooting
Every error a web call page can receive, what causes it and how to fix it, plus dropped calls and browser requirements.
Two places can fail: your server when it creates the call, and the page when it connects. They report differently, so check the right one first.
From your server (creating the call)
| Response | Meaning and fix |
|---|---|
401 | The API key is missing, wrong, expired or revoked. See Get your API keys. |
403 with INSUFFICIENT_SCOPE | The key lacks the scope this call needs. Make a new key with it. |
404 | No such agent in this organization. |
409 web_origins_not_configured | No website is allowed yet. See Tokens and allowed websites. |
422 | A field is invalid, for example an agent_version that does not exist. |
402 | The organization cannot pay for a call. Add credit in Billing. |
429 | More than the per-minute limit of calls were created. Wait for Retry-After. |
From the page (connecting)
The page receives an error event with a code, a message fit to show the visitor and, where it applies, a reason.
code | reason | Meaning and fix |
|---|---|---|
mic_denied | The visitor refused the microphone. Explain why you need it and let them try again. | |
mic_unavailable | The device has no microphone, or another app holds it. | |
token_unavailable | Your function that fetches the token failed. Check your /api/start-call endpoint and its logs. | |
refused | origin_not_allowed | The page's origin is not in the allow-list. Match scheme, host and port exactly. |
refused | token_expired | More than 60 seconds passed. Request the token when the visitor clicks. |
refused | token_already_used | The token was already spent. Create a new call for each attempt. |
refused | token_invalid | The token is malformed or was changed. |
busy | concurrency_limit_reached | Too many calls are running in your organization. |
call_refused | for example insufficient_credit, org_suspended | The call was declined. reason says why. |
unsupported | The browser lacks what a call needs, or a Content-Security-Policy blocks the audio processor. | |
server_error, connection_failed | A failure on the way. Try again. |
A call that drops
A call that loses its connection has ended with reason: "connection_lost". There is no reconnecting: the conversation lives on the server for as long as the connection does, and the token is single-use. Tell the visitor, and start a new call with a new token.
Content-Security-Policy
The audio processor loads from a blob: URL, so a policy with a script-src must include blob:. Without it the page gets unsupported. Example:
Content-Security-Policy: script-src 'self' blob:Browser requirements
- Chrome 66+, Edge 79+, Firefox 76+ or Safari 14.1+.
- Served over HTTPS, or from
localhost. call.start()runs from a click or tap. Browsers only let a page play sound after one.- The microphone permission is allowed for the site.
Checklist when a call will not connect
- Does
POST /api/start-callon your server return a token? If not, read the table above. - Is the page's exact origin in the allow-list?
- Is the call started from a click handler?
- Is the page on HTTPS, or
localhost? - Does your Content-Security-Policy allow
blob:, and any connection rules you set? - Does the organization have credit, and the agent a voice?
For fixes to problems that are not specific to web calls, see Troubleshooting.