client.audio.speech(...) -> GetSpeechResponse
-
-
-
Synthesize speech audio from text or SSML. Returns the complete audio file plus billing and speech-mark metadata in a single JSON response. For low-latency playback or long-form text, use POST /v1/audio/stream. Set
output_formatfor explicit sample-rate/bitrate control (e.g.pcm_16000orulaw_8000for telephony).
-
-
-
from speechify import Speechify from speechify.environment import SpeechifyEnvironment client = Speechify( token="<token>", environment=SpeechifyEnvironment.DEFAULT, ) client.audio.speech( audio_format="mp3", input="Hello! This is the Speechify text-to-speech API.", model="simba-3.2", voice_id="geffen_32", )
-
-
-
input:
strPlain text or SSML to be synthesized to speech. Refer to https://docs.speechify.ai/docs/api-limits for the input size limits. Emotion, Pitch and Speed Rate are configured in the ssml input, please refer to the ssml documentation for more information: https://docs.speechify.ai/docs/ssml#prosody
-
voice_id:
str— Id of the voice to be used for synthesizing speech. Refer to /v1/voices endpoint for available voices
-
audio_format:
typing.Optional[GetSpeechRequestAudioFormat]— The format for the output audio. Note, that the current default is "wav", but there's no guarantee it will not change in the future. We recommend always passing the specific param you expect.
-
language:
typing.Optional[str]Language of the input. Follow the format of an ISO 639-1 language code and an ISO 3166-1 region code, separated by a hyphen, e.g. en-US. Please refer to the list of the supported languages and recommendations regarding this parameter: https://docs.speechify.ai/docs/language-support.
-
model:
typing.Optional[GetSpeechRequestModel]— Model used for audio synthesis. Defaults tosimba-3.0, which is streaming-native and multilingual: it officially supports English plusde-DE,es-ES,es-MX,fr-FR,it-ITandpt-BR, and routes each request to its English or its multilingual training based onlanguage(falling back to the voice's locale whenlanguageis omitted).simba-3.2is the streaming-native model with the lowest TTFB and richest expressivity, and the recommended Simba 3 model; it is English only, so a non-English voice returns 400.simba-englishandsimba-multilingualare the legacy Simba 1.6 models, kept for compatibility.
-
options:
typing.Optional[GetSpeechOptionsRequest]
-
output_format:
typing.Optional[AudioOutputFormat]— The output audio format as acodec_sampleRate_bitratestring. Takes precedence overaudio_formatwhen set.
-
request_options:
typing.Optional[RequestOptions]— Request-specific configuration.
-
-
client.audio.stream(...) -> typing.Iterator[bytes]
-
-
-
Synthesize speech and stream the audio back as it is generated, for low-latency playback. Set
output_formatin the body for explicit codec/sample-rate/bitrate control (e.g.pcm_16000orulaw_8000for telephony), or fall back to the Accept header for the container; the response is raw audio bytes (HTTP chunked). For Base64-encoded audio with speech-mark metadata in a single JSON response, use POST /v1/audio/speech.
-
-
-
from speechify import Speechify from speechify.environment import SpeechifyEnvironment client = Speechify( token="<token>", environment=SpeechifyEnvironment.DEFAULT, ) client.audio.stream( input="input", voice_id="voice_id", )
-
-
-
request:
GetStreamRequest
-
accept:
typing.Optional[StreamAudioRequestAccept]Selects the audio container/codec for the streamed response when
output_formatis not set in the request body. The response Content-Type echoes this value, exceptaudio/pcmreturnsaudio/L16with rate and channels parameters (raw 16-bit linear PCM, 24 kHz mono, little-endian). For explicit sample-rate/bitrate control (e.g.pcm_16000,ulaw_8000), setoutput_formatin the body instead; it takes precedence over this header.
-
request_options:
typing.Optional[RequestOptions]— Request-specific configuration.
-
-
client.audio.stream_with_timestamps(...) -> typing.Iterator[bytes]
-
-
-
Synthesize speech and stream it back together with word-level speech marks, for text highlighting, captions and audio-text synchronization while the audio is still arriving.
The response is a Server-Sent Events stream. Each
speech.chunkevent carries a Base64-encoded run of audio, the speech marks that became final with it, or both - a chunk may carry only one of the two, and the last chunk of a stream is often marks-only. A terminalspeech.doneevent ends the stream; there is no[DONE]sentinel. Ignore any event type you do not recognize, so that new event types do not break your integration.Speech-mark times are absolute milliseconds from the start of the synthesis, so concatenate the audio chunks into one stream and apply the marks against that single timeline. Which chunk a mark arrives on is a delivery detail and carries no meaning. Times stay correct for every
output_format: changing the codec or sample rate does not change the duration.Speech marks are produced by the streaming-native models. The default
simba-3.0andsimba-3.2both serve this route; the legacysimba-englishandsimba-multilingualmodels return 400speech_marks_unsupportedhere. For Base64-encoded audio and speech marks in one non-streamed JSON response, on any model, use POST /v1/audio/speech.
-
-
-
from speechify import Speechify from speechify.environment import SpeechifyEnvironment client = Speechify( token="<token>", environment=SpeechifyEnvironment.DEFAULT, ) client.audio.stream_with_timestamps( input="Streaming long-form audio with the Speechify API.", model="simba-3.2", voice_id="geffen_32", )
-
-
-
request:
GetStreamRequest
-
accept:
typing.Optional[StreamWithTimestampsAudioRequestAccept]Selects the audio container/codec carried inside the events when
output_formatis not set in the request body. The selected media type is echoed on theSpeechify-Audio-Content-Typeresponse header, since the response's own Content-Type istext/event-stream.
-
request_options:
typing.Optional[RequestOptions]— Request-specific configuration.
-
-
client.models.list() -> ModelsResponse
-
-
-
List the text-to-speech models available for synthesis. Drive a model picker from this response, then pass a model
idas themodelparameter to POST /v1/audio/speech or /v1/audio/stream. The response marks the default model (used when a request omitsmodel), the routes each model may be passed to, and which voices it accepts. Multi-speaker models arrive in a separatedialogue_modelsarray because they are valid only on POST /v1/audio/dialogue. Returns the full set in a single response: the model catalog is static platform reference data, so it is intentionally not paginated.
-
-
-
from speechify import Speechify from speechify.environment import SpeechifyEnvironment client = Speechify( token="<token>", environment=SpeechifyEnvironment.DEFAULT, ) client.models.list()
-
-
-
request_options:
typing.Optional[RequestOptions]— Request-specific configuration.
-
-
client.voices.list(...) -> ListVoicesResponse
-
-
-
Lists the voices available to the caller - the shared voice catalog plus the workspace's cloned voices, whichever member or service-account key created them. By default the full catalogue is returned in one response. Pagination is opt-in: pass
limit(and thencursorfrom the previous response) to page through the list whilehas_moreis true. Max page size is 200. Narrow the list with thetypeandlocalefilters (applied before pagination, so pages stay full).
-
-
-
from speechify import Speechify from speechify.environment import SpeechifyEnvironment client = Speechify( token="<token>", environment=SpeechifyEnvironment.DEFAULT, ) client.voices.list( locale="en", model="simba-3.2", )
-
-
-
cursor:
typing.Optional[str]— Opaque pagination cursor from a previous response.
-
limit:
typing.Optional[int]— Max items per page (default 50, max 200).
-
type:
typing.Optional[ListVoicesRequestType]Filter by voice type:
personal(the workspace's cloned voices) orshared(the public catalogue). Omit to return both.
-
locale:
typing.Optional[str]Filter to voices whose locale matches this BCP-47 language range, prefix-matched:
enmatchesen-USanden-GB;en-USmatches onlyen-US. Case-insensitive. Omit to return all locales.
-
gender:
typing.Optional[ListVoicesRequestGender]— Filter by voice gender. Omit to return all genders.
-
model:
typing.Optional[str]Filter to voices that support this model (as listed in each voice's
models[]), e.g.simba-3.2. Omit to return voices for all models.
-
request_options:
typing.Optional[RequestOptions]— Request-specific configuration.
-
-
client.voices.create(...) -> GetVoice
-
-
-
Create a cloned voice for the workspace from a 10-30 second audio sample, with verified consent from the speaker.
Cloning requires proof that the speaker agreed to it. Create a consent challenge with
POST /v1/voices/consent-challenges, show the returnedphraseto the speaker, record them reading it aloud, and send that recording here asconsent_recordingtogether with the challenge'sconsent_challenge_id. Speechify transcribes the recording, checks it against the phrase it issued, checks that its speaker is the speaker in yoursample, and keeps it as the consent record for the voice. The person consenting therefore has to be the person being cloned. A challenge is single use and short-lived, so record and submit in one sitting.The clone belongs to the workspace rather than the member who created it, and access follows the caller's workspace role and API-key scopes exactly as for any other voice: voices scopes to list it, audio scopes to synthesize with it, and the content-management permission plus a write scope on the key to delete it. Cloned voices are usable self-serve on
simba-3.0,simba-englishandsimba-multilingual.simba-3.2also serves cloned voices, currently as a limited release enabled per workspace; contact Speechify to have it enabled for yours.Callers pinned before
Speechify-Version: 2026-09-13use the previous flow instead: no challenge, and aconsentform field carrying the speaker's name and email as a JSON string. That flow is deprecated and will be removed after a sunset window announced in the changelog.
-
-
-
from speechify import Speechify from speechify.environment import SpeechifyEnvironment client = Speechify( token="<token>", environment=SpeechifyEnvironment.DEFAULT, ) client.voices.create( idempotency_key="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", sample="example_sample", avatar="example_avatar", consent_recording="example_consent_recording", name="name", gender="male", consent_challenge_id="consent_challenge_id", )
-
-
-
name:
str— Name of the personal voice
-
gender:
CreateVoicesRequestGenderGender marker for the personal voice male GenderMale female GenderFemale not_specified GenderNotSpecified
-
sample:
core.File— Audio sample of the voice to clone, 10-30 seconds of clean speech.
-
consent_challenge_id:
strThe
idof the consent challenge this create consumes, fromPOST /v1/voices/consent-challenges. Single use: once a create has consumed it, whether or not that create succeeded, it cannot be used again.
-
consent_recording:
core.FileRecording of the speaker reading the challenge's
phrasealoud. This is the consent record for the voice, not a second voice sample: it must be the same person as insample, and it is retained as evidence. 5-30 seconds, at most 25 MB, in any common audio container.
-
idempotency_key:
typing.Optional[str]A client-generated key (an opaque string, max 255 chars) that makes a side-effect POST safe to retry: the server runs the operation exactly once and replays the first response (its status and body) for 24 hours. Reusing a key with a different request body, or while the first request is still in flight, returns
409 idempotency_conflict. A replayed response carries theIdempotent-Replayed: trueheader.
-
locale:
typing.Optional[str]— Native language (locale) of the personal voice (e.g. en-US, es-ES, etc.)
-
avatar:
typing.Optional[core.File]— Avatar image file
-
request_options:
typing.Optional[RequestOptions]— Request-specific configuration.
-
-
client.voices.get(...) -> GetVoice
-
-
-
Fetch a single voice by id - a shared catalogue voice or one of the workspace's cloned voices. A cloned voice that belongs to another workspace returns 404, identical to an unknown id, so voice inventory is never enumerable across tenants.
-
-
-
from speechify import Speechify from speechify.environment import SpeechifyEnvironment client = Speechify( token="<token>", environment=SpeechifyEnvironment.DEFAULT, ) client.voices.get( voice_id="voice_id", )
-
-
-
voice_id:
str— The ID of the voice to fetch
-
request_options:
typing.Optional[RequestOptions]— Request-specific configuration.
-
-
client.voices.delete(...)
-
-
-
Delete one of the workspace's cloned voices. Requires the
content.managepermission (owner, admin, or member); a service-account key is authorized by its scopes instead.
-
-
-
from speechify import Speechify from speechify.environment import SpeechifyEnvironment client = Speechify( token="<token>", environment=SpeechifyEnvironment.DEFAULT, ) client.voices.delete( voice_id="voice_id", )
-
-
-
voice_id:
str— The ID of the voice to delete
-
request_options:
typing.Optional[RequestOptions]— Request-specific configuration.
-
-
client.voices.download_sample(...) -> typing.Iterator[bytes]
-
-
-
Download a personal (cloned) voice sample
-
-
-
from speechify import Speechify from speechify.environment import SpeechifyEnvironment client = Speechify( token="<token>", environment=SpeechifyEnvironment.DEFAULT, ) client.voices.download_sample( voice_id="voice_id", )
-
-
-
voice_id:
str— The ID of the voice to download sample for
-
request_options:
typing.Optional[RequestOptions]— Request-specific configuration.
-
-
client.voices.consent_challenges.create(...) -> ConsentChallenge
-
-
-
Start the consent check for a voice clone.
Returns a
phrasefor the speaker to read aloud and anidthat identifies this challenge. Show the phrase to the speaker exactly as returned, record them reading it, then send the recording and theidtoPOST /v1/voices, which verifies the recording against the phrase and against the voice sample being cloned, then keeps it as the consent record.A challenge is single use, is bound to the workspace that created it, and expires at
expires_at- it is proof that a speaker was in front of a microphone just now, so create it when you are ready to record, not at the start of your flow. If it expires, create another one and record again.Challenge creation is rate limited per workspace at a few dozen per hour, far more tightly than the rest of the voice surface, because each one precedes a person recording themselves - mint it when your speaker is ready, not speculatively. Read the live ceiling off
RateLimit-*rather than hard-coding it. On a429, always honourRetry-Afterrather than a fixed backoff of your own: the wait is measured in minutes and can run to most of an hour.RateLimit-*are omitted rather than reporting a bucket that is not the one refusing.
-
-
-
from speechify import Speechify from speechify.environment import SpeechifyEnvironment client = Speechify( token="<token>", environment=SpeechifyEnvironment.DEFAULT, ) client.voices.consent_challenges.create( idempotency_key="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", full_name="Jane Doe", )
-
-
-
full_name:
strFull name of the person consenting to have their voice cloned. Speechify binds it to the challenge and stores it with the consent record, so the create that consumes the challenge does not carry it and cannot change it.
At most 120 bytes once UTF-8 encoded, which is 120 characters of Latin script but around 40 of Chinese, Japanese or Korean. Stated in bytes rather than as a
maxLengthbecause the two only agree on single-byte scripts, and a character count that never over-accepts would have to refuse Latin names at 30. A name over the limit comes back asvalidation_failedreporting its measured length.
-
idempotency_key:
typing.Optional[str]A client-generated key (an opaque string, max 255 chars) that makes a side-effect POST safe to retry: the server runs the operation exactly once and replays the first response (its status and body) for 24 hours. Reusing a key with a different request body, or while the first request is still in flight, returns
409 idempotency_conflict. A replayed response carries theIdempotent-Replayed: trueheader.
-
request_options:
typing.Optional[RequestOptions]— Request-specific configuration.
-
-