Docs /Getting Started//v1/audio/speech

/v1/audio/speech

Create speech as raw audio, JSON/base64, or server-sent events.

HTTP request

POST https://api.featherless.ai/v1/audio/speech

Authenticate with Authorization: Bearer <FEATHERLESS_API_KEY> and send a JSON body. The maximum request body is 50 MiB, including base64 reference audio.

Every example on this page reads your key from the FEATHERLESS_API_KEY environment variable, so export it once before running any of them. The Python examples need pip install requests. The TypeScript examples use top-level await, so save each one with an .mjs extension, or set "type": "module" in package.json, and run it on Node 18 or newer, which supplies the built-in fetch they rely on.

Generate binary audio
curl --fail-with-body https://api.featherless.ai/v1/audio/speech \
  --header "Authorization: Bearer $FEATHERLESS_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "model": "hexgrad/Kokoro-82M",
    "input": "Text to synthesize.",
    "voice": "af_bella",
    "response_format": "wav",
    "speed": 1,
    "delivery": "bulk",
    "encoding": "binary"
  }' \
  --output speech.audio \
  --write-out "Content-Type: %{content_type}\n"

Request body

{
  "model": "hexgrad/Kokoro-82M",
  "input": "Text to synthesize.",
  "voice": "af_bella",
  "response_format": "mp3",
  "speed": 1,
  "delivery": "bulk",
  "encoding": "binary"
}

model

Required string. The exact speech-model ID returned by the model catalog.

input

Required non-empty string. Featherless does not impose one global text-length ceiling; each model applies its own limit. Expression and speaker syntax, when supported, is written directly into this string.

voice

Optional. Accepts a preset name string, a custom ID object, or a voice-cloning object. A model can reject any variant it does not support. Omit the field to use the default voice for the model.

Voice variants
"voice": "af_bella"

"voice": { "id": "custom_voice_id" }

"voice": {
  "clone": {
    "audio": {
      "data": "<bare base64 audio>",
      "format": "wav"
    },
    "reference_text": "Exact transcript of the reference clip."
  }
}

response_format

Optional enum: mp3, opus, aac, flac, wav, or pcm. Defaults to MP3. Query the voices endpoint for formats accepted for a model. This field is a request, not a guarantee: audio can still arrive in the format the model natively produces, because Featherless only rewraps PCM as WAV and never transcodes between codecs. Inspect the actual response metadata.

speed

Optional number from 0.25 through 4. Defaults to 1. A value outside that range fails validation before any audio is produced. Within the range, speed is not guaranteed to affect the output for every model, and some models have a narrower range described in their guide.

instructions

Optional string for speaking-style guidance. It is not guaranteed to affect the output for a given model. Only use it when the selected model guide marks it as exposed.

delivery and encoding

Delivery can be bulk, json, or stream. The default is bulk. Bulk uses raw binary unless encoding is base64; JSON always returns one base64 envelope; stream always uses SSE base64 events.

stream and stream_format aliases

For compatibility, stream: true selects SSE, stream_format: sse selects SSE, and stream_format: audio selects bulk audio. When multiple selectors are present, precedence is delivery, then stream_format, then stream.

Successful response headers

Every successful mode returns X-Generation-Id, X-Request-Id, and X-Input-Characters. The two ID headers contain the same request identifier.

JSON response

{
  "object": "audio.speech",
  "format": "wav",
  "usage": {
    "input_characters": 18,
    "output": [
      { "unit": "byte", "quantity": 42144 },
      { "unit": "second", "quantity": 2.63 }
    ]
  },
  "audio": "<base64 audio>"
}

The second-based output measurement is best effort and may be omitted. Speech is billed on input characters, not on the output measurements shown here.

Unknown and model-specific fields

Unrecognized top-level fields are accepted for forward compatibility, return 200 with audio, and are discarded. A success response is never evidence that a field was honored. Parameters such as exaggeration, cfg_weight, language, and other sampling controls currently have no effect unless they become explicit public API fields.

Errors

{
  "error": {
    "message": "Voice is not available for this model.",
    "type": "invalid_request_error",
    "code": "invalid_voice"
  }
}

Schema validation failures return 422. Named 400 codes include unsupported_format, invalid_voice, and cloning_unsupported. Other common speech error codes include unsupported_clone_format, insufficient_credits, model_not_found, and internal_server_error. If binary or SSE delivery terminates after the response begins, the HTTP status cannot be replaced; SSE clients must treat a missing speech.audio.done event as a failed stream.

Last edited: Aug 26, 2026