oaitts · /v1/audio/speech · part of tts

oaitts

oaitts speaks text through OpenAI-compatible speech APIs. Those APIs take plain text and, for models that follow them, an instructions field written in natural language rather than numeric settings, so oaitts writes the instructions from the same flags its Azure sibling turns into SSML. Any compatible endpoint works: OpenAI, a local proxy, or a gateway in front of another provider.

From flags to instructions

Flags become instructions How oaitts turns delivery flags into the instructions field of an OpenAI speech request, as printed by oaitts --print-request. Your own --instructions come first; then --lang becomes 'Speak in the language fr-FR.', --style 'Speak in a shouting style.', --degree 'Use style intensity 1.5 on a scale where 1 is normal and 2 is strong.', --role 'Speak as if you are imitating a pirate.', --pitch=-5 'Use a pitch 5% lower than your normal pitch.', and --volume 80 'Use 80% of your normal speaking volume.' --instructions 'Warm and unhurried.' --lang fr-FR --style shouting --degree 1.5 --role 'a pirate' --pitch=-5 --volume 80 “Warm and unhurried.” “Speak in the language fr-FR.” “Speak in a shouting style.” “Use style intensity 1.5 on a scale where 1 is normal and 2 is strong.” “Speak as if you are imitating a pirate.” “Use a pitch 5% lower than your normal pitch.” “Use 80% of your normal speaking volume.”
Each sentence is real output. Every line was printed by oaitts --print-request; they compose in this order.
oaitts --print-request --style cheerful --lang en-GB 'Your build has finished.'
{"input":"Your build has finished.","instructions":"Speak in the language en-GB. Speak in a cheerful style.",
 "model":"gpt-4o-mini-tts","response_format":"pcm","speed":1.0,"voice":"alloy"}

These are qualitative directions, not exact signal processing: a 5% pitch drop is a request the model may honour approximately or not at all, and compliance varies by model. What oaitts never does is invent API fields the endpoint doesn't define, or quietly drop a control the model can't follow:

oaitts --print-request --model tts-1 --style cheerful 'Hi'
oaitts: this OpenAI model has no instruction support; remove prompt controls or select a prompted voice model (compatible servers can set providers.openai.instructions-supported)
[exit 2]

The request

The request is the standard JSON: model, input, voice, response_format, speed (0.25–4) and, when there is anything to say, instructions. It defaults to gpt-4o-mini-tts and the voice alloy, but any compatible model and voice ID are accepted: there is no allowlist.

The base URL comes from OPENAI_BASE_URL and may be an origin, a /v1 URL, a proxy prefix or the complete speech URL; it is normalised once, never doubling /v1. Plain HTTP is allowed for a local proxy, redirects are not followed, and the key travels only as a Bearer header from OPENAI_API_KEY.

  • Not Azure in disguise. No SSML, no Azure Speech JSON and no speaker embeddings; those are refused, not translated.
  • No surprises in a pinned door. oaitts always means OpenAI-compatible and never falls back. For ordered fallback across providers, use tts unpinned.
  • Everything else is shared. Raw and file output, stdin line handling, the daemon, FIFO playback, cancellation, panning and mute are the tts core's.