Web calls
A web call is a conversation with an inbound agent started from a browser on your own site: the visitor's microphone is the phone. It runs on the same voice models, tools, extraction and delivery as a phone call, and it uses minutes like one (without the telephony part of the cost).
Publishable keys
A web call opens with a publishable key (alt_pub_…), created in the console under Integrations → Keys → Site keys. A publishable key:
- names one published inbound agent;
- is accepted by browsers only from the origins you list (
https://www.example.com, up to 10); - opens at most 2 calls at a time and 100 a day, one waiting call and a few per minute per visitor.
It is meant to sit in your site's HTML: it cannot read data, change agents or place outbound calls. The origin check stops other sites' pages, not a script that forges the header, so the limits are what bound the minutes a key can use. Revoke it from the console to stop it at once.
The widget
The quickest way: copy the snippet of a key from the console (Copy snippet) and paste it into your site's pages, before </body>:
<script
src="https://api.allerto.cloud/widget.js"
data-key="alt_pub_…"
async
></script>
A button appears in the bottom-right corner; the visitor taps it, allows the microphone and talks to the agent, with live captions. The widget has Allerto's look on every site, in black or, with data-theme="light" on the script tag, in cream; its button text is set per key in the console and reaches every site on the next page load, with no change to the snippet. It tells the visitor they are talking to an AI assistant.
If your site sends a Content Security Policy, allow https://api.allerto.cloud in script-src and https://api.allerto.cloud wss://api.allerto.cloud wss://voice.allerto.cloud in connect-src.
To build your own interface instead, use the endpoint and the stream below.
Starting a call
POST https://api.allerto.cloud/v1/web-calls
Authorization: Bearer alt_pub_…
{
"call_id": "6f2c…",
"stream": "wss://…/voice/web?token=…",
"expires_at": "2026-10-20T12:01:00.000Z"
}
The browser must open stream within 20 seconds. The request is answered with CORS headers for your origin.
If your page asks the visitor for their number before the call, send it in the body. It becomes the call's from, the agent does not ask for it again, and the result's callback_phone gets it when the agent defines that field. It is not verified: treat it like a caller ID.
POST https://api.allerto.cloud/v1/web-calls
Authorization: Bearer alt_pub_…
Content-Type: application/json
{ "phone": "+393331234567" }
| Error | Status | Meaning |
|---|---|---|
missing_publishable_key | 401 | No Authorization: Bearer alt_pub_… |
invalid_publishable_key | 401 | Unknown or revoked key |
origin_not_allowed | 403 | The page's origin is not in the key's list |
invalid_phone | 400 | phone is not in international format (+39…) |
rate_limited | 429 | Too many calls from this visitor |
agent_busy | 429 | The key already has its maximum of calls open |
agent_unavailable | 503 | The agent is not published, archived or suspended |
The stream
One WebSocket carries audio both ways:
- You send binary frames of 16-bit little-endian mono PCM at 16 kHz (20 ms frames work well), and
{"type":"stop"}to hang up. - You receive binary frames of 16-bit little-endian mono PCM at 24 kHz to play in order, and JSON text events (tool calls are never sent to a site's visitor):
| Event | When |
|---|---|
{"type":"started","call_id","model"} | The agent is connected and about to greet |
{"type":"state","transcript","tools"} | The transcript or tool calls changed (transcript: [{role,text}]) |
{"type":"interrupted"} | The visitor spoke over the agent: drop the audio not yet played |
{"type":"ended","call_id","error"} | The call is over |
A call lasts at most 6 minutes. When it ends it is processed like a phone call: the result is extracted and delivered to the agent's delivery (email and/or call.completed webhook, with livemode: true). The call's from is the visitor's phone when sent, otherwise the page's origin.