curl -X POST https://api.telzino.com/v1/voice/sessions \
-H "Authorization: Bearer pk_live_..." \
-H "Origin: https://example.com" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "3f1c2a4e-8b7d-4c3a-9e2f-1a2b3c4d5e6f",
"participant_name": "Ada",
"metadata": { "plan": "pro" }
}'
curl -X POST https://api.telzino.com/v1/voice/sessions \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "3f1c2a4e-8b7d-4c3a-9e2f-1a2b3c4d5e6f",
"end_user": { "id": "user_8231", "name": "Ada", "email": "[email protected]" },
"metadata": { "plan": "pro" }
}'
{
"session_id": "vs_8fK2mQx9LpR4tYb7Wn3cZ1aD",
"agent": { "id": "3f1c2a4e-8b7d-4c3a-9e2f-1a2b3c4d5e6f", "name": "Front Desk" },
"livekit": {
"url": "wss://...",
"room": "agent-3f1c2a4e-8b7d-4c3a-9e2f-1a2b3c4d5e6f-1730000000000-k3x9pq",
"token": "eyJ..."
},
"expires_at": "2026-11-02T18:30:00Z"
}
{
"error": "origin_not_allowed",
"error_description": "This origin is not allowed for the publishable key"
}
{
"error": "rate_limited",
"error_description": "Daily session cap reached"
}
Sessions
Voice Sessions
Start a browser voice session with a Telzino agent
POST
/
v1
/
voice
/
sessions
curl -X POST https://api.telzino.com/v1/voice/sessions \
-H "Authorization: Bearer pk_live_..." \
-H "Origin: https://example.com" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "3f1c2a4e-8b7d-4c3a-9e2f-1a2b3c4d5e6f",
"participant_name": "Ada",
"metadata": { "plan": "pro" }
}'
curl -X POST https://api.telzino.com/v1/voice/sessions \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "3f1c2a4e-8b7d-4c3a-9e2f-1a2b3c4d5e6f",
"end_user": { "id": "user_8231", "name": "Ada", "email": "[email protected]" },
"metadata": { "plan": "pro" }
}'
{
"session_id": "vs_8fK2mQx9LpR4tYb7Wn3cZ1aD",
"agent": { "id": "3f1c2a4e-8b7d-4c3a-9e2f-1a2b3c4d5e6f", "name": "Front Desk" },
"livekit": {
"url": "wss://...",
"room": "agent-3f1c2a4e-8b7d-4c3a-9e2f-1a2b3c4d5e6f-1730000000000-k3x9pq",
"token": "eyJ..."
},
"expires_at": "2026-11-02T18:30:00Z"
}
{
"error": "origin_not_allowed",
"error_description": "This origin is not allowed for the publishable key"
}
{
"error": "rate_limited",
"error_description": "Daily session cap reached"
}
Creates a LiveKit room, dispatches the agent into it and returns a short-lived participant token for the caller. The Voice SDK calls this endpoint for you.
There are two authentication modes. Both send
For a publishable key, responses to an allowed origin carry CORS headers. So do
Authorization: Bearer <credential>.
| Publishable key | Secret key | |
|---|---|---|
| Credential | pk_live_... | Access token from /oauth/token |
| Called from | The browser | Your server |
| Origin | The request Origin must be one of the key’s allowed origins | Not checked. No CORS headers. |
| Agent access | The key’s scope and agent allowlist | The key’s scope |
end_user | Ignored | Passed to the agent |
ttl_seconds max | 900 | 3600 |
| Limits | 60/min per key, 10/min per key and IP, and a daily session cap (default 2,000) | None |
invalid_key and origin_not_allowed whenever the request has a valid Origin, so the browser can read the error.
Background data about the caller, passed to the agent. String values only, at most 4096 bytes of JSON. This is data, never instructions.
Participant token lifetime, from 60 up to 900 with a publishable key or 3600 with a secret key.
curl -X POST https://api.telzino.com/v1/voice/sessions \
-H "Authorization: Bearer pk_live_..." \
-H "Origin: https://example.com" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "3f1c2a4e-8b7d-4c3a-9e2f-1a2b3c4d5e6f",
"participant_name": "Ada",
"metadata": { "plan": "pro" }
}'
curl -X POST https://api.telzino.com/v1/voice/sessions \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "3f1c2a4e-8b7d-4c3a-9e2f-1a2b3c4d5e6f",
"end_user": { "id": "user_8231", "name": "Ada", "email": "[email protected]" },
"metadata": { "plan": "pro" }
}'
{
"session_id": "vs_8fK2mQx9LpR4tYb7Wn3cZ1aD",
"agent": { "id": "3f1c2a4e-8b7d-4c3a-9e2f-1a2b3c4d5e6f", "name": "Front Desk" },
"livekit": {
"url": "wss://...",
"room": "agent-3f1c2a4e-8b7d-4c3a-9e2f-1a2b3c4d5e6f-1730000000000-k3x9pq",
"token": "eyJ..."
},
"expires_at": "2026-11-02T18:30:00Z"
}
{
"error": "origin_not_allowed",
"error_description": "This origin is not allowed for the publishable key"
}
{
"error": "rate_limited",
"error_description": "Daily session cap reached"
}
Response
The response is sent withCache-Control: no-store.
Errors
Errors use one shape:{ "error": "<code>", "error_description": "<message>" }.
| Status | error | Meaning |
|---|---|---|
| 400 | invalid_request | The body failed validation. |
| 401 | invalid_key | Unknown or revoked publishable key, or an invalid secret-key token. |
| 403 | origin_not_allowed | The Origin is not on the publishable key. |
| 403 | embed_disabled | The Voice SDK is turned off for the account. |
| 404 | agent_not_found | No such agent, it is outside the key’s scope or allowlist, or it is not live. |
| 429 | rate_limited | Burst limit or daily session cap reached (publishable key only). |
| 503 | livekit_unavailable | The session could not be started. Retry shortly. |
CORS preflight
OPTIONS /v1/voice/sessions answers 204. CORS headers echo the Origin only when the preflight can proceed for it. Browsers send no Authorization header on a preflight, so the key and origin are checked for real on the POST.