> ## Documentation Index
> Fetch the complete documentation index at: https://docs.inworld.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Create speech (OpenAI-compatible)

> Generate audio from text in OpenAI's text-to-speech format

Generate audio from text using the format of OpenAI's [`/v1/audio/speech`](https://platform.openai.com/docs/api-reference/audio/createSpeech) endpoint. To use the OpenAI SDKs with Inworld, set the base URL, API key, model, and voice to Inworld values. See [OpenAI Compatibility](https://docs.inworld.ai/tts/openai-compatibility.md) for SDK examples, audio formats, and streaming.

## API reference

**Endpoint:** `POST https://api.inworld.ai/v1/audio/speech`

### Authorization

- `Authorization` (string; required) — Your [authentication](https://docs.inworld.ai/api-reference/introduction.md) credentials. Pass your API key as a Bearer token: `Bearer $INWORLD_API_KEY`. The OpenAI SDKs send the key this way.

### Request body

Content type: `application/json`

- `model` (string; required) — An Inworld model ID. See [Models](https://docs.inworld.ai/tts/tts-models.md). OpenAI model names such as `tts-1` are rejected.
- `input` (string; required) — The text to synthesize, up to 4,000 characters. Inline markup such as [steering tags](https://docs.inworld.ai/tts/capabilities/steering.md) and [pause controls](https://docs.inworld.ai/tts/capabilities/pause-controls.md) is supported.
- `voice` (string; required) — An Inworld voice ID, or the ID of one of your custom voices. Voice IDs are case-sensitive. OpenAI voice names such as `alloy` are not available.
- `response_format` (enum<string>; default: "mp3"; options: "mp3", "opus", "flac", "wav", "pcm") — The audio format. `mp3`, `opus`, `flac`, and `wav` are 48 kHz mono. `pcm` is raw 16-bit signed little-endian mono samples at 24 kHz, with no header. `aac` is not supported.
- `speed` (number; default: 1) — The speaking rate. Values outside 0.5 to 1.5 are rejected.
- `instructions` (string) — A natural-language [steering](https://docs.inworld.ai/tts/capabilities/steering.md) instruction for the whole request. Supported on `inworld-tts-2` only; other models ignore it.
- `stream_format` (enum<string>; default: "audio"; options: "audio", "sse") — `audio` streams raw audio bytes. `sse` streams server-sent events.

#### Request example

```json
{
  "model": "inworld-tts-2",
  "input": "Welcome back! Your order shipped this morning and should arrive by Thursday.",
  "voice": "Dennis"
}
```

### Response examples

#### 200: default_response

```json
"string"
```

#### 400: default_response

```json
{
  "error": {
    "message": "speed must be between 0.5 and 1.5",
    "type": "invalid_request_error",
    "param": "speed",
    "code": null
  }
}
```

#### 401: default_response

```json
{
  "error": {
    "message": "authentication is required",
    "type": "authentication_error",
    "param": null,
    "code": null
  }
}
```

#### 402: default_response

```json
{
  "error": {
    "message": "string",
    "type": "invalid_request_error",
    "param": "string",
    "code": "string"
  }
}
```

#### 403: default_response

```json
{
  "error": {
    "message": "string",
    "type": "invalid_request_error",
    "param": "string",
    "code": "string"
  }
}
```

#### 404: default_response

```json
{
  "error": {
    "message": "Unknown voice: alloy not found!",
    "type": "invalid_request_error",
    "param": null,
    "code": null
  }
}
```

#### 429: default_response

```json
{
  "error": {
    "message": "string",
    "type": "invalid_request_error",
    "param": "string",
    "code": "string"
  }
}
```

#### 5XX: default_response

```json
{
  "error": {
    "message": "string",
    "type": "invalid_request_error",
    "param": "string",
    "code": "string"
  }
}
```

### Code examples

#### cURL

```bash
curl -X POST https://api.inworld.ai/v1/audio/speech \
  -H "Authorization: Basic $INWORLD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "inworld-tts-2",
    "voice": "Dennis",
    "input": "Welcome back! Your order shipped this morning and should arrive by Thursday."
  }' \
  --output speech.mp3
```

#### Python

```python
import requests

url = "https://api.inworld.ai/v1/audio/speech"
payload = {
  "model": "inworld-tts-2",
  "input": "Welcome back! Your order shipped this morning and should arrive by Thursday.",
  "voice": "Dennis"
}
headers = {
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
}

response = requests.request("POST", url, json=payload, headers=headers)

print(response.text)
```

#### JavaScript

```javascript
const options = {method: 'POST', headers: {"Authorization":"Bearer <token>","Content-Type":"application/json"}, body: JSON.stringify({
  "model": "inworld-tts-2",
  "input": "Welcome back! Your order shipped this morning and should arrive by Thursday.",
  "voice": "Dennis"
})};

fetch('https://api.inworld.ai/v1/audio/speech', options)
  .then(response => response.json())
  .then(response => console.log(response))
  .catch(err => console.error(err));
```

#### Python (OpenAI SDK)

```python
from openai import OpenAI

client = OpenAI(
    base_url="https://api.inworld.ai/v1",
    api_key="YOUR_INWORLD_API_KEY",
)

with client.audio.speech.with_streaming_response.create(
    model="inworld-tts-2",
    voice="Dennis",
    input="Welcome back! Your order shipped this morning and should arrive by Thursday.",
) as response:
    response.stream_to_file("speech.mp3")
```

#### Node (OpenAI SDK)

```javascript
import fs from 'node:fs';
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://api.inworld.ai/v1',
  apiKey: 'YOUR_INWORLD_API_KEY',
});

const response = await client.audio.speech.create({
  model: 'inworld-tts-2',
  voice: 'Dennis',
  input: 'Welcome back! Your order shipped this morning and should arrive by Thursday.',
});

fs.writeFileSync('speech.mp3', Buffer.from(await response.arrayBuffer()));
```
