> ## 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.

# Core API

> TelzinoVoice and VoiceCall reference for @telzino/voice

`@telzino/voice` is the framework-independent browser client.

```sh theme={null}
npm i @telzino/voice
```

## `new TelzinoVoice(config)`

```ts theme={null}
import { TelzinoVoice } from '@telzino/voice';

const voice = new TelzinoVoice({ publishableKey: 'pk_live_...' });
```

| Member | Type | Description |
| - | - | - |
| `config.publishableKey` | `string` | Publishable key (`pk_...`). Safe in the browser, but only works from allowed origins. |
| `config.session` | `(req: SessionRequest) => Promise<SessionResponse>` | Custom session provider, used instead of the key. See [Authentication](https://docs.telzino.com/sdk/authentication.md). |
| `config.apiBaseUrl` | `string` | Defaults to `https://api.telzino.com`. During the beta, use `https://beta.telzino.io`. |
| `activeCall` | `VoiceCall \| null` | The call in progress, if any. |
| `start(opts)` | `(opts: StartOptions) => Promise<VoiceCall>` | `opts` is `{ agentId, participantName?, metadata? }`. Rejects with `invalid_request` if a call is already active. |
| `listInputDevices()` | `() => Promise<Array<{ deviceId: string; label: string }>>` | Available microphones. Labels are empty until mic permission is granted. |

Provide either `publishableKey` or `session`. With neither, `start()` rejects with `invalid_request`.

### `start(opts, hooks?)`

```ts theme={null}
const call = await voice.start({
  agentId: '3f1c2a4e-8b7d-4c3a-9e2f-1a2b3c4d5e6f',
  participantName: 'Ada',
  metadata: { plan: 'pro' },
});
```

| Option | Type | Description |
| - | - | - |
| `agentId` | `string` | The id (UUID) of the agent to call. |
| `participantName` | `string` | Display name of the caller. Up to 80 characters. Defaults to "Guest". |
| `metadata` | `Record<string, string>` | String values only, up to 4096 bytes as JSON. Background data about the caller, not instructions. See [Security](https://docs.telzino.com/sdk/security.md). |

`start()` asks for microphone permission, so call it from a user gesture such as a button click.

The optional second argument `hooks` is `{ onCall?: (call: VoiceCall) => void }`. `onCall` fires synchronously once the call object exists, before it emits `connecting`. Use it to subscribe to events from the start, or to call `end()` while the call is still connecting.

## `VoiceCall`

`start()` resolves to a `VoiceCall` once the connection is up.

| Member | Type | Description |
| - | - | - |
| `sessionId` | `string` | Server session id. |
| `agent` | `{ id: string; name: string }` | The agent being called. |
| `status` | `CallStatus` | `idle`, `connecting`, `connected`, `reconnecting` or `ended`. |
| `agentState` | `AgentState` | `initializing`, `listening`, `thinking`, `speaking` or `unknown`. |
| `transcript` | `TranscriptItem[]` | Live transcript, `{ id, role, text, final, timestamp }`. |
| `messages` | `ChatMessage[]` | Text chat messages, `{ id, role, text, timestamp }`. |
| `muted` | `boolean` | Whether the microphone is muted. |
| `needsUserGesture` | `boolean` | True when the browser blocked audio playback; call `resumeAudio()` from a click. |
| `on(event, fn)` | `(event, fn) => () => void` | Subscribe; returns an unsubscribe function. See [Events and errors](https://docs.telzino.com/sdk/events.md). |
| `setMuted(muted)` | `Promise<void>` | Mute or unmute the microphone. |
| `sendText(text)` | `Promise<void>` | Send a text chat message to the agent. |
| `setInputDevice(deviceId)` | `Promise<void>` | Switch microphone. |
| `resumeAudio()` | `Promise<void>` | Start audio playback after a user gesture. |
| `end()` | `Promise<void>` | Hang up. Safe to call more than once. |

```ts theme={null}
call.on('transcript', (item) => console.log(item.role, item.text, item.final));
call.on('agentState', (state) => console.log('agent is', state));
call.on('ended', ({ reason }) => console.log('call ended:', reason));

await call.setMuted(true);
await call.setMuted(false);

await call.end();
```

A transcript item can be updated several times while a line is spoken. `final` is `false` for partial text and `true` once the line is complete. Items keep the same `id` across updates.

## Audio playback

Browsers can block audio until the user interacts with the page. When that happens, `needsUserGesture` becomes `true` and a `needsUserGesture` event fires. Show a button and call `resumeAudio()` from its click handler.

## Choosing a microphone

```ts theme={null}
const devices = await voice.listInputDevices();
await call.setInputDevice(devices[0].deviceId);
```

Device labels are empty until the user grants microphone permission.


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