---
title: "Synthesize speech and hold it for a later commit"
method: POST
path: "/legs/{id}/tts/preflight"
tags: ["Legs"]
---

# Synthesize speech and hold it for a later commit

`POST /legs/{id}/tts/preflight`

Stages a speculative reply. The audio is synthesized and buffered in memory but not played, so that committing it starts playback with no synthesis delay. Intended for the turn-taking loop of a voice agent: start a draft reply on the `eager_end_of_turn` `stt.turn` event, then commit it on `end_of_turn` or discard it on `turn_resumed`. A `tts.staged` event reports when the audio is ready; synthesis failures are reported on `tts.error`. Staged utterances are dropped after `TTS_PREFLIGHT_TTL` or when the leg ends, and at most `TTS_PREFLIGHT_MAX_PER_LEG` may be staged on one leg at a time. Preflight is leg-scoped; use `POST /rooms/{id}/tts` for room announcements.

## Request body

- TTSRequest
  - `text` string, required — Text to synthesize
  - `voice` string, required — Provider-specific voice identifier. ElevenLabs: voice name or ID. AWS Polly: voice ID (e.g. Joanna, Matthew). Google Cloud: voice name — either full format (e.g. en-US-Neural2-F) or short name for Gemini models (e.g. Achernar, Kore). Deepgram: model name (e.g. aura-2-asteria-en).
  - `model_id` string, required — Provider-specific model/engine. ElevenLabs: model ID. AWS Polly: engine (standard, neural, long-form, generative; default neural). Google Cloud: model name (e.g. gemini-2.5-pro-tts, chirp3-hd).
  - `language` string — Language code (e.g. "en-US", "pl-pl"). Required for Google Gemini TTS voices that use short names (e.g. Achernar). Auto-extracted from full voice names like en-US-Neural2-F.
  - `prompt` string — Style/tone instruction for promptable voice models (Google Gemini TTS only). E.g. "Read aloud in a warm, welcoming tone."
  - `volume` integer, required — Volume adjustment in dB (-8 to 8)
  - `provider` 'elevenlabs' | 'aws' | 'google' | 'deepgram' — TTS provider: "elevenlabs" (default), "aws", "google", or "deepgram"
  - `api_key` string — ElevenLabs: API key override (falls back to ELEVENLABS_API_KEY env var). AWS: optional ACCESS_KEY:SECRET_KEY override (falls back to default AWS credential chain). Google Cloud: optional API key override (falls back to Application Default Credentials). Deepgram: API key override (falls back to DEEPGRAM_API_KEY env var).

## Response `200`

TTS staged

- StatusResponse
  - `instance_id` string — Instance identifier
  - `status` string, required

## Other responses

- `400` — Invalid JSON, missing text/voice, or volume out of range
- `404` — Leg not found
- `409` — Leg has no audio writer, or too many staged utterances on this leg
- `503` — No API key provided for the selected provider

---

[API](https://skmtc.net/voiceblender/apis/voiceblender-api.md) · [All operations](https://skmtc.net/voiceblender/apis/voiceblender-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/voiceblender/voiceblender-api/revisions/571f8c004e74/schema)
