Other clients
OpenAI API drop-in
OpenAI's own speech API through the cache: keep the OpenAI SDK, change the base URL and key.
OpenAI's Python SDK#
OpenAI’s speech API, mirrored under https://api.ttscacherouter.dev/openai/v1. Keep the OpenAI SDK: pass the router as its base_url and your router API key as its api_key.
import osfrom openai import OpenAIclient = OpenAI( base_url="https://api.ttscacherouter.dev/openai/v1", api_key=os.environ["TTS_CACHE_ROUTER_API_KEY"],)with client.audio.speech.with_streaming_response.create( model="gpt-4o-mini-tts", voice="ash", input="Your order has shipped. It arrives on Friday.", instructions="Speak in a warm, friendly tone.",) as response: response.stream_to_file("speech.mp3")audio.speech.create works through the router with every model, voice, format and setting, streamed or not. Requests, responses, status codes and error bodies are OpenAI’s own; your body is forwarded as you sent it, with the OpenAI key stored under Provider keys. For a LiveKit agent, see OpenAI with LiveKit.
This is OpenAI’s API, with OpenAI’s model names. The router’s own /v1/audio/speech takes the same request with openai/gpt-4o-mini-tts as the model, and serves every provider.
Speech#
POST /openai/v1/audio/speech: the audio in the requestedresponse_format, or withstream_format: "sse"OpenAI’sspeech.audio.deltaevents (tts-1andtts-1-hdanswer that with the audio, as OpenAI does).
Any other path under /openai answers 404.
curl -N https://api.ttscacherouter.dev/openai/v1/audio/speech \ -H "Authorization: Bearer $TTS_CACHE_ROUTER_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "tts-1", "voice": "alloy", "input": "Your order has shipped.", "response_format": "pcm"}' \ --output speech.pcmcurl -N https://api.ttscacherouter.dev/openai/v1/audio/speech \ -H "Authorization: Bearer $TTS_CACHE_ROUTER_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "gpt-4o-mini-tts", "voice": "ash", "input": "Your order has shipped.", "response_format": "pcm", "stream_format": "sse"}'What is cached#
- Each request as a whole: the same body again replays the same audio, in every format.
- With
stream_format: "sse", a reply from the cache sends the samespeech.audio.deltaevents, thenspeech.audio.donewith zero usage (OpenAI spent no tokens on it), then[DONE]. - A reply from the cache carries only
Content-Type: no OpenAI request produced it, so there is nox-request-id. gpt-4o-mini-ttsis an alias OpenAI can move to a newer snapshot; audio already cached under it keeps the voice it was made with. To pin the voice, name a snapshot such asgpt-4o-mini-tts-2025-12-15.
Errors#
A wrong or missing router key gets OpenAI’s own refusal, HTTP 401. So does an org with no OpenAI key stored, with a message that links to the dashboard. Errors from OpenAI, such as a voice the model doesn’t have, reach you as OpenAI sent them.
HTTP/1.1 401 Unauthorized{"error": {"message": "Incorrect API key provided.", "type": "invalid_request_error", "param": null, "code": "invalid_api_key"}}