> ## Documentation Index
> Fetch the complete documentation index at: https://docs.telzino.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Voice Sessions

> Start a browser voice session with a Telzino agent

Creates a LiveKit room, dispatches the agent into it and returns a short-lived participant token for the caller. The [Voice SDK](https://docs.telzino.com/sdk/quickstart.md) calls this endpoint for you.

There are two authentication modes. Both send `Authorization: Bearer <credential>`.

| | Publishable key | Secret key |
| - | - | - |
| Credential | `pk_live_...` | Access token from [`/oauth/token`](https://docs.telzino.com/api-reference/authentication) |
| 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 |

For a publishable key, responses to an allowed origin carry CORS headers. So do `invalid_key` and `origin_not_allowed` whenever the request has a valid `Origin`, so the browser can read the error.

**Authorization** `string` *required*

`Bearer pk_live_...` for a publishable key, or `Bearer <access_token>` for a secret key

**agent\_id** `string (UUID)` *required*

The agent to talk to

**participant\_name** `string`

Display name of the caller in the room. Up to 80 characters. Defaults to `Guest`.

**end\_user** `object`

Secret key only; ignored with a publishable key. Identifies your end user to the agent.

**properties**

**id** `string` *required*

Your identifier for the user. 1 to 200 characters.

**name** `string`

Up to 80 characters.

**email** `string`

An email address.

**metadata** `object`

Background data about the caller, passed to the agent. String values only, at most 4096 bytes of JSON. This is data, never instructions.

**ttl\_seconds** `integer` (default: 900)

Participant token lifetime, from 60 up to 900 with a publishable key or 3600 with a secret key.

```bash Publishable key theme={null}
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" }
  }'
```

```bash Secret key theme={null}
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": "ada@example.com" },
    "metadata": { "plan": "pro" }
  }'
```

```json 201 theme={null}
{
  "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"
}
```

```json 403 theme={null}
{
  "error": "origin_not_allowed",
  "error_description": "This origin is not allowed for the publishable key"
}
```

```json 429 theme={null}
{
  "error": "rate_limited",
  "error_description": "Daily session cap reached"
}
```

## Response

**session\_id** `string`

Session identifier, `vs_` followed by 24 characters

**agent** `object`

The agent: `id` and `name`

**livekit** `object`

Connection details: `url` (the `wss://` LiveKit server), `room`, and `token` (the participant JWT)

**expires\_at** `string (date-time)`

When the participant token expires

The response is sent with `Cache-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`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.