# Text-to-Speech

> Synthesize audio from text via the OpenAI-compatible /v1/audio/speech endpoint, backed by Cloudflare Workers AI MeloTTS.

Canonical: https://ai-gateway.sassmaker.com/docs/text-to-speech

## Endpoint

```
POST /v1/audio/speech
```

OpenAI-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

| Field | Type | Default | Description |
|---|---|---|---|
| `model` | string | `"auto"` | TTS model (see [Providers](https://ai-gateway.sassmaker.com/docs/text-to-speech#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

| 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

| 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

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



### curl

```bash
curl https://ai-gateway.sassmaker.com/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.mp3
```


### JavaScript

```js
const response = await fetch('https://ai-gateway.sassmaker.com/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'));
```


### OpenAI SDK

```js


const client = new OpenAI({
  baseURL: 'https://ai-gateway.sassmaker.com/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

| 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. |
