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

# LiveKit Agents

> Give a LiveKit voice agent a Finesse voice with the Node.js plugin, @flamai/livekit-plugin-finesse.

The Finesse plugin for [LiveKit Agents](https://docs.livekit.io/agents/) is the text-to-speech for
your voice agent: a voice from the catalog or one you cloned, speaking any of 60 languages.

* **Realtime**: the agent's reply streams to Finesse as the LLM writes it, so speech starts before
  the reply is finished.
* **Interruptions**: when the user talks over the agent, the reply is cancelled on the Finesse server
  straight away.
* **Telephony**: 8 kHz audio for phone calls, or up to 48 kHz for everything else.

> **[npm](https://www.npmjs.com/package/@flamai/livekit-plugin-finesse)**
>
> `@flamai/livekit-plugin-finesse`, for Node 20+ and `@livekit/agents` 1.9+.

> **[Source on GitHub](https://github.com/homingos/livekit-finesse)**
>
> `homingos/livekit-finesse`, Apache-2.0.

> [!NOTE]
>
> The plugin is for Node.js. Python support for LiveKit Agents is coming soon.

## Install

```bash npm theme={null}
npm install @flamai/livekit-plugin-finesse
```

```bash pnpm theme={null}
pnpm add @flamai/livekit-plugin-finesse
```

```bash yarn theme={null}
yarn add @flamai/livekit-plugin-finesse
```

Create an API key in the [dashboard](https://finesse.flamapp.ai/dashboard) under
**Developers → API Keys**, and put it in your agent's environment, where the plugin reads it:

```bash theme={null}
export FINESSE_API_KEY="flv_..."
```

Keep the key on your server. See [Authentication](https://docs.finesse.flamapp.ai/guides/authentication.md).

## Add it to your agent

Set `tts` on your `AgentSession` to a Finesse `TTS` with the id of a `ready` voice:

```ts agent.ts theme={null}
import {
  type JobContext,
  ServerOptions,
  cli,
  defineAgent,
  inference,
  voice,
} from '@livekit/agents';
import * as finesse from '@flamai/livekit-plugin-finesse';
import { fileURLToPath } from 'node:url';

export default defineAgent({
  entry: async (ctx: JobContext) => {
    const session = new voice.AgentSession({
      stt: new inference.STT({ model: 'deepgram/nova-3', language: 'en' }),
      llm: new inference.LLM({ model: 'openai/gpt-4.1-mini' }),
      tts: new finesse.TTS({ voice: '<voice-id>' }),
    });

    await session.start({
      agent: new voice.Agent({ instructions: 'You are a friendly voice assistant.' }),
      room: ctx.room,
    });
    await ctx.connect();
    session.generateReply({ instructions: 'Greet the user.' });
  },
});

cli.runApp(new ServerOptions({ agent: fileURLToPath(import.meta.url) }));
```

Run it with `tsx agent.ts dev` and talk to it in the
[Agents Playground](https://agents-playground.livekit.io). Already have an agent? The only change is
the `tts` line.

To find a voice id, copy one from **Voices** in the dashboard, or call
[List voices](https://docs.finesse.flamapp.ai/voice-api/list-voices.md). Cloned voices work like any other. See [Voices](https://docs.finesse.flamapp.ai/concepts/voices.md).

## Options

| Option | Default | Description |
| - | - | - |
| `voice` | required | The id of a `ready` voice, from the catalog or one you cloned. |
| `language` | `"en"` | The language to speak, such as `hi`, `ta` or `arz`. Region tags work: `hi-IN` is Hindi, `ar-EG` is Egyptian Arabic. |
| `sampleRate` | `24000` | Output rate in Hz: `8000` for telephony, or from `24000` up to `48000`. Audio is 16-bit mono PCM. |
| `numStep` | `32` | Quality versus latency, from 1 to 32. Lower is faster. |
| `guidanceScale` | `2.0` | Synthesis guidance, from 0 to 10. |
| `lengthScale` | `1.0` | Speaking rate, above 0 up to 5. Higher is slower. |
| `idleFlushMs` | `800` | When the LLM pauses mid-sentence, speak the pending text after this many milliseconds. From 200 to 5000. |
| `apiKey` | `FINESSE_API_KEY` | Your Finesse API key. |

`updateOptions()` changes the voice, language or synthesis settings from the agent's next reply:

```ts theme={null}
tts.updateOptions({ voice: '<another-voice-id>', language: 'ta' });
```

## Phone calls

For SIP and telephony agents, ask for 8 kHz so the audio goes to the call without resampling:

```ts theme={null}
new finesse.TTS({ voice: '<voice-id>', sampleRate: 8000 });
```

## Connections and limits

Replies share a pool of WebSocket connections, so only the first reply pays to connect. Call
`tts.prewarm()` when the agent starts to open one early. Each open connection holds one of your
plan's concurrent streams: see [Rate limits](https://docs.finesse.flamapp.ai/guides/rate-limits.md).

## Errors

Errors are LiveKit's `APIStatusError`, `APIConnectionError` and `APITimeoutError`, so they work with
`AgentSession` error events and LiveKit's fallback adapter. Errors that can't succeed on a retry are
marked `retryable: false`.

| Code or status | What it means |
| - | - |
| `401` | The API key is missing, wrong, revoked or expired. |
| `voice_not_found` | The voice doesn't exist, isn't visible to your workspace, or isn't `ready` yet. |
| `insufficient_credits` | The workspace is out of credits. Top up from **Billing** in the dashboard. |
| `invalid_language` | `language` isn't a Finesse language. |
| `429` | Over your plan's request rate or concurrent streams. Retried automatically. |
| `503` | Finesse is briefly at capacity. Retried automatically. |

See [Errors](https://docs.finesse.flamapp.ai/voice-api/errors.md) for every code. The plugin streams over the
[Realtime WebSocket](https://docs.finesse.flamapp.ai/voice-api/realtime-websocket.md), so everything there applies.


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