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

# nika:tts_generate

> Usage, declared contract and source links for this Nika builtin.

export const Ecosystem = () => <CardGroup cols={3}>
    <Card title="Documentation" icon="book" href="/introduction">
      Guides, reference contracts and working examples.
    </Card>
    <Card title="Nika Lab" icon="diagram-project" href="https://github.com/supernovae-st/nika-lab">
      Internal workspace and graph projections of the spec, documentation and code.
    </Card>
    <Card title="Language spec" icon="file-contract" href="https://github.com/supernovae-st/nika-spec">
      the nine-key envelope, Apache-2.0. The contract these docs explain.
    </Card>
    <Card title="Engine source" icon="gem" href="https://github.com/supernovae-st/nika">
      Rust, AGPL-3.0-or-later. Every commit public.
    </Card>
    <Card title="TypeScript SDK" icon="code" href="/sdk/overview">
      Use one typed lifecycle locally or against authenticated nika serve HTTP.
    </Card>
    <Card title="Editor extension" icon="puzzle-piece" href="https://marketplace.visualstudio.com/items?itemName=supernovae.nika-lang">
      VS Code · Cursor · Windsurf: check-as-you-type, DAG view, trace replay.
    </Card>
    <Card title="Homebrew tap" icon="beer-mug-empty" href="https://github.com/supernovae-st/homebrew-tap">
      `brew install supernovae-st/tap/nika` for the latest tagged CLI release.
    </Card>
    <Card title="SuperNovae" icon="star" href="https://supernovae.studio">
      The Paris studio crafting Nika. 🦋
    </Card>
  </CardGroup>;

[Builtins catalog](/reference/builtins) / `nika:tts_generate`

<CardGroup cols={2}>
  <Card title="Media" icon="layer-group">Tool family from the canonical registry.</Card>
  <Card title="invoke" icon="code" href="/reference/language/words/invoke">Call this builtin through the invoke verb.</Card>
</CardGroup>

## Read this contract

This reference preserves the specification at the revision linked below. Source examples are **fragments**: their surrounding tasks, inputs and permissions are not supplied here. Consult [engine status](/reference/status) and `nika catalog --tools --json` for the installed implementation; a registry declaration is not a runtime qualification.

## Usage and behavior

```yaml illustration theme={"system"}
narrate:
    invoke:
      tool: "nika:tts_generate"
      args:
        provider: local              # sovereign first — or openai · elevenlabs · mock
        text: "Bienvenue — the launch is live."
        voice: "alloy"
        output_dir: "./assets/audio"
```

Teaching shape · [`17-tts-self`](https://github.com/supernovae-st/nika-spec/blob/f8c5df2127c7867b2e51a2cd5712fa9d8461e73e/examples/17-tts-self.nika.yaml)
(`provider: mock` · a real WAV · offline).

The image family's contract, applied to audio: ONE audio file lands under
`output_dir:` (permit-gated per final path BEFORE I/O · atomic write ·
content-hash-named `{stem}-{provider}-{model}-{sha8}.{ext}` so identical
re-runs are idempotent), the output carries `&#123; provider, model, voice,
created_at, endpoint_host, audio: &#123; path, filename, format, mime_type,
size_bytes, sha256, duration_ms &#125;, cost_usd, warnings, manifest_path,
output_dir &#125;` — **audio bytes NEVER ride outputs**, and a sidecar
provenance manifest (`manifest: true` default) echoes the resolved
request.

| Arg                                                        | Contract                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `provider`                                                 | REQUIRED-or-inferred · closed: `local` (any OpenAI-speech-compatible self-hosted server — LocalAI · Kokoro-FastAPI · Speaches · openedai-speech · ONE wire: `POST {base}/v1/audio/speech` → raw bytes · base URL is ENGINE CONFIG `NIKA_TTS_LOCAL_URL`, default `http://localhost:8080`, never workflow data · never inferred) · `openai` · `elevenlabs` · `mock` (a REAL deterministic WAV · zero network/keys). Inference: `eleven*` → elevenlabs · `gpt-*`/`tts-*` → openai · `mock*` → mock. |
| `model`                                                    | per-provider default (reference engine 2026-07: `tts-1` local convention · `gpt-4o-mini-tts` · `eleven_multilingual_v2` · `mock-tts-1`)                                                                                                                                                                                                                                                                                                                                                          |
| `text`                                                     | REQUIRED · non-empty · ≤4096 chars (the strictest documented wire cap, held portably — fan longer scripts out with `for_each`)                                                                                                                                                                                                                                                                                                                                                                   |
| `voice`                                                    | provider voice id · defaults: `alloy` (openai/local) · Rachel's public id (elevenlabs — ids are path components, so engines MUST restrict them to the id alphabet) · `sine` (mock)                                                                                                                                                                                                                                                                                                               |
| `format`                                                   | `mp3 \| wav \| auto` (default auto = provider-native) — the saved EXTENSION follows the sniffed bytes (magic authority), never the ask; a lossy fold is a `format_mismatch:` warning                                                                                                                                                                                                                                                                                                             |
| `speed`                                                    | 0.25–4.0 (openai/local native) — warned-dropped (`speed_unsupported:`) where the wire has no knob                                                                                                                                                                                                                                                                                                                                                                                                |
| `output_dir` · `filename_prefix` · `metadata` · `manifest` | as `image_generate` (stem falls back to `metadata.page_slug`, then `speech`)                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `timeout_ms`                                               | default 120000 · local 300000 (CPU synthesis) · max 600000                                                                                                                                                                                                                                                                                                                                                                                                                                       |

**Validation (engine MUST)** · the payload is sniffed (WAV `RIFF…WAVE` ·
MP3 `ID3`/frame-sync) — a non-audio payload is a hard `-007`; WAV
`duration_ms` is exact header math, MP3 duration is honestly `null`
(never a guess). Empty payloads are `-004`.

**Security (engine MUST)** · endpoints are engine-fixed constants (the
`local` base URL is engine config at the composition root — the same
sanction as `image_generate` and `infer:`) · keys are engine-configured
(`OPENAI_API_KEY` · `ELEVENLABS_API_KEY` · `NIKA_TTS_LOCAL_API_KEY` or
the `NIKA_`-prefixed forms), never workflow args, never logged · a
verbose local server reflecting the Bearer into an error body MUST be
scrubbed (the image family's rule).

Throws · `NIKA-BUILTIN-TTS_GENERATE-001` invalid arguments
(`validation_error`) · `-002` provider unavailable (`validation_error`) ·
`-003` request failed (`network_error` · `transient: true` for
5xx/408/429 + timeout/connection) · `-004` empty audio (`tool_error`) ·
`-005` content policy (`security_error` · never transient) · `-006` save
failed (`tool_error`) · `-007` payload validation (`tool_error`) — the
image twin's category ladder, code for code.

## Related concepts

<CardGroup cols={2}>
  <Card title="Arguments" icon="sliders" href="/reference/language/words/args">Pass the values required by the tool contract.</Card>
  <Card title="Permissions" icon="shield" href="/concepts/security">Understand authority before granting effects.</Card>
  <Card title="Errors and recovery" icon="rotate" href="/reference/error-codes">Read diagnostics and choose a recovery policy.</Card>
  <Card title="Workflow templates" icon="file-code" href="/guides/templates">Put the fragment inside a complete workflow.</Card>
</CardGroup>

## Contract provenance

[Read the pinned specification](https://github.com/supernovae-st/nika-spec/blob/f8c5df2127c7867b2e51a2cd5712fa9d8461e73e/stdlib/builtins-v0.1.md#L757) · [Canonical registry](https://github.com/supernovae-st/nika-spec/blob/f8c5df2127c7867b2e51a2cd5712fa9d8461e73e/canon/builtins.yaml).

Tool identity: `nika:tts_generate`. Specification revision: `f8c5df2127c7`.
The Lab language identity is `language:tool:tts_generate`; the registry view is `ecosystem:tool/nika:tts_generate`. They refer to this contract without merging their graph identities.

<Ecosystem />
