Tokens and allowed websites
How the one-use call token works, how to allow your websites, and the limits that apply to web calls.
A web call is safe to start from a browser because of two things: a token that is worth almost nothing if it leaks, and an allow-list of the websites that may use it.
The token
Your server creates a call with POST /v1/calls/web and gets back an access_token. It is not your API key. It is a signed value that already contains everything the call needs: which call, which agent, which organization and which websites may use it. The page cannot change any of that.
| Lifetime | 60 seconds. Request it when the visitor clicks, not in advance. |
| Use | Once. The first connection spends it; a second is refused with token_already_used. |
| Scope | One call, with one agent, in one organization. |
| Unused | If a token is never used, the call is closed as failed with disconnection reason web_call_not_started a few minutes later. |
The create response also tells you expires_at and expires_in, and which agent_version the call will run.
What the page cannot do
The token decides everything. A page cannot:
- choose a different agent, or a different organization;
- change the agent's prompt, voice or tools;
- change
metadataor the dynamic variables, which your server fixed when it created the call; - point the call's webhook somewhere else.
Anything else the page sends is ignored.
Allow your websites
Before the first call, list the websites that may start calls: Settings, Web calls in the dashboard, or the API.
curl -X PUT https://api.dialgem.com/v1/web-calls/settings \
-H "X-API-Key: $DIALGEM_API_KEY" -H "Content-Type: application/json" \
-d '{ "allowed_origins": ["https://www.example.com", "https://*.example.com", "http://localhost:3000"] }'An origin is scheme://host[:port] with no path, for example https://www.example.com. Rules:
https://*.example.comallows every subdomain, but notexample.comitself. List both if you need both.*allows any website. Use it only for a public demo.http://localhost:3000is fine while developing; remove it before you launch if you do not need it.- The scheme and port must match exactly:
https://example.comandhttp://example.comare different origins.
Until at least one origin is listed, creating a call answers 409 web_origins_not_configured. Setting the list replaces the old one.
What the allow-list protects against
A browser always sends its page's origin when it connects, and a page cannot forge it. So the allow-list stops another website from using a token it got hold of. It does not stop someone who already has a token and is not using a browser. That is what the 60 second life and single use are for: a token is spent the first time it is presented, so a copy that leaks is useless the moment the real page connects.
Limits
| Limit | Default | When it is hit |
|---|---|---|
| Calls at once | 10 per organization | The next visitor's call is refused with busy. |
| Calls created | 60 a minute per organization | More answer 429 with a Retry-After header. Wait that long before retrying. |
| Billing | Like any other call | Creating one answers 402 if the organization cannot pay, and the call is refused at connect if that changed in between. |
The two limits protect you as much as Dialgem: a script that hammers your /api/start-call endpoint would otherwise run up your bill. Put your own rate limit and login check on that endpoint.