Nari Labs narration
Use nari-tts alongside ElevenLabs through VideoClaw's existing narration and dialogue commands. Narration produces artifacts/audio/narration.wav and artifacts/narration.json, ready for the existing audio assembly path. Existing backend priority is unchanged; select Nari explicitly with --backend nari-tts.
Secure setup
Revoke the key previously pasted into chat in your Nari account and create a replacement. Never reuse it, commit it, put it in a prompt or pass it as a CLI argument.
Configure NARI_API_KEY using your environment or the workspace .env.local secrets file, outside the installed package. The CLI loads this file from the workspace selected by --root. Keep it excluded from version control. Library callers can pass env: { NARI_API_KEY: secret } to the narration API; an explicit environment is authoritative.
| Setting | Default | Purpose |
|---|---|---|
NARI_API_KEY | Required | Nari bearer credential |
NARI_TTS_MODEL | qwen3-tts:free | One of qwen3-tts:free, qwen3-tts-fast:free, qwen3-tts, qwen3-tts-fast |
--voice | diana | Case-sensitive model-specific voice ID, such as leon |
The selected voice determines the language. VideoClaw omits language so Nari uses that voice's assigned language; it does not translate the script. Consult the model's current voice catalogue before selecting a voice. Partner models require access and credits; free models have usage limits.
Generate narration
For an existing project, after configuring a replacement key:
vclaw video narrate --project my-film --backend nari-tts \
--voice diana --text "Welcome to our film." --confirm-spendAdd --root /path/to/workspace when using a non-default workspace. Use --text-file script.txt for a script file. The existing generation confirmation gate also applies to free models.
For an offline CLI check, use a dummy environment value and a dry run:
NARI_API_KEY=offline-placeholder vclaw video narrate --project my-film \
--backend nari-tts --text "Welcome to our film." --dry-runA dry run writes a zero-byte placeholder and estimated duration, not playable audio. Run it in a test project: it updates narration artefacts. The backend itself needs no credential in dry-run mode, but the narration command's existing availability gate requires a non-empty value.
Limits and failure behaviour
- Each trimmed script must contain 1–2,048 Unicode code points. Split longer scripts at sentence boundaries; this adapter does not silently truncate or split them. Each dialogue turn uses its own request.
- Requests use
POST https://api.narilabs.com/v1/audio/speech, complete-response WAV, and a 120-second deadline including response consumption. JSON bodies must fit within 64 KiB. - Successful audio is validated as 24 kHz, PCM16 little-endian mono WAV. Duration comes from the delivered sample count, not a text-length estimate. Narration's existing duration probe remains in place.
- HTTP, network, timeout and invalid-audio failures use the existing
tts_failederror. Errors include HTTP status where available, without API response bodies, credentials or raw network exception text. - Generation is not retried automatically because a lost response may already have consumed allowance. Check Nari request logs and quota before retrying. Authentication failures need a valid key; 403 may require model access; 429 requires checking concurrency/daily limits; 5xx may be transient.
- Explicit
--backend nari-ttsnever falls back to another provider. Without explicit selection, the existing narration fallback order may reach Nari when its credential is configured.
Verification
Offline coverage is in src/tests/audio-platform-tts-nari.test.ts. After npm run build, run:
node --test dist/tests/audio-platform-tts-nari.test.jsAn optional live smoke test is the generation command above, run with a fresh key and a test project. Play the resulting WAV and check its duration before treating live voice quality as verified. Offline tests do not prove account access or live voice quality.
API contract checked 13 September 2026: speech generation, voices, models, limits.
