Text-to-Speech
Endpoint
Section titled “Endpoint”POST /v1/audio/speechOpenAI-compatible text-to-speech. Returns raw audio bytes (mp3, wav, or opus). Drop-in compatible with the OpenAI client.audio.speech.create() API.
Request Body
Section titled “Request Body”| Field | Type | Default | Description |
|---|---|---|---|
model | string | "auto" | TTS model (see Providers). Use "auto" for health-aware routing. |
input | string | required | Text to speak. 1–10,000 chars. |
voice | string | "alloy" | One of alloy, echo, fable, onyx, nova, shimmer (Workers AI MeloTTS). |
response_format | string | "mp3" | One of "mp3", "wav", "opus", "flac". Actual formats served depend on provider. |
speed | number | 1.0 | Playback speed multiplier, 0.25–4.0. Honoured by providers that expose it. |
project_id | string | — | Body-level project tag. Alternative to x-gateway-project-id header. |
Required Header
Section titled “Required Header”| Header | Required | Description |
|---|---|---|
Authorization: Bearer <GATEWAY_API_KEY> | yes | Gateway API key. |
x-gateway-project-id | yes (or body project_id) | 1–64 chars [a-zA-Z0-9._:-]. |
x-gateway-force-provider | no | Pin to workers_ai or groq. |
Providers
Section titled “Providers”| Provider | Model | Voices | Status |
|---|---|---|---|
| Cloudflare Workers AI | @cf/myshell-ai/melotts | alloy, echo, fable, onyx, nova, shimmer | Enabled — no external key, uses Workers AI binding. |
| Groq PlayAI | playai-tts | — | :warning: Disabled — Groq deprecated playai-tts on their free tier. Kept in the registry for future re-enablement but currently returns no_tts_provider. |
Response
Section titled “Response”Binary audio bytes. The Content-Type matches the served format:
| Format | Content-Type |
|---|---|
| mp3 | audio/mpeg |
| wav | audio/wav |
| opus | audio/opus |
Response Headers:
| Header | Description |
|---|---|
x-gateway-provider | Provider that served the request (e.g. workers_ai). |
x-gateway-model | Exact model used. |
x-gateway-project-id | Echoes the resolved project id. |
Examples
Section titled “Examples”curl https://free-ai-gateway.sarthakagrawal927.workers.dev/v1/audio/speech \ -H "Authorization: Bearer <GATEWAY_API_KEY>" \ -H "x-gateway-project-id: my_project" \ -H "Content-Type: application/json" \ -d '{ "model": "auto", "input": "Hello world. This is the free AI gateway speaking.", "voice": "nova", "response_format": "mp3" }' \ --output speech.mp3const response = await fetch('https://free-ai-gateway.sarthakagrawal927.workers.dev/v1/audio/speech', { method: 'POST', headers: { 'Authorization': 'Bearer <GATEWAY_API_KEY>', 'x-gateway-project-id': 'my_project', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'auto', input: 'Hello world. This is the free AI gateway speaking.', voice: 'nova', response_format: 'mp3', }),});
const audioBlob = await response.blob();const url = URL.createObjectURL(audioBlob);new Audio(url).play();
console.log('Served by:', response.headers.get('x-gateway-provider'));import OpenAI from 'openai';import fs from 'fs';
const client = new OpenAI({ baseURL: 'https://free-ai-gateway.sarthakagrawal927.workers.dev/v1', apiKey: '<GATEWAY_API_KEY>', defaultHeaders: { 'x-gateway-project-id': 'my_project' },});
const mp3 = await client.audio.speech.create({ model: 'auto', voice: 'shimmer', input: 'Hello from Claude and the free AI gateway.',});
const buffer = Buffer.from(await mp3.arrayBuffer());await fs.promises.writeFile('speech.mp3', buffer);Error Codes
Section titled “Error Codes”| Status | code | Meaning |
|---|---|---|
| 400 | invalid_project_id | Missing/invalid project_id. |
| 502 | provider_error | All TTS candidates failed. Last upstream error is included in the message. |
| 503 | no_tts_provider | No TTS binding/key configured. |