> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.tramlabs.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.tramlabs.io/_mcp/server.

# Text-to-Speech

> Cách tạo âm thanh giọng nói từ văn bản với các model của Trạm AI

Trạm AI hỗ trợ text-to-speech (TTS) thông qua endpoint chuyên dụng `/v1/audio/speech`, tương thích với [OpenAI Audio Speech API](https://platform.openai.com/docs/api-reference/audio/createSpeech). Người dùng gửi văn bản và nhận về một byte stream âm thanh thô ở định dạng được lựa chọn.

## Khám phá model

Người dùng có thể tìm các model TTS theo nhiều cách:

### Qua API

Dùng [Public Models API](/tong-quan/models#public-models-api-publicmodels) để lấy danh sách model, sau đó lọc các model có `mode` là `"audio_speech"`:

**`lines`**

```bash lines
# Lấy danh sách tất cả model
curl "https://api.tramlabs.io/public/models"

# Tìm model TTS: lọc các model có mode = "audio_speech"
```

### Trên trang Models

Truy cập [trang Models](/tong-quan/models) và lọc theo output modalities để tìm các model có khả năng tổng hợp giọng nói. Hãy tìm model nào có liệt kê `"speech"` trong output modalities.

## Sử dụng API

Gửi một request `POST` tới `/v1/audio/speech` kèm văn bản cần tổng hợp. Response trả về là một byte stream âm thanh thô — không phải JSON — nên người dùng có thể đưa thẳng nó vào một file hoặc trình phát âm thanh.

### Ví dụ cơ bản

**`TypeScript`**

```typescript title="TypeScript" expandable lines
import OpenAI from 'openai';
import fs from 'fs';

const openai = new OpenAI({
  baseURL: 'https://api.tramlabs.io/v1',
  apiKey: '{{API_KEY_REF}}',
});

const response = await openai.audio.speech.create({
  model: '{{MODEL}}',
  input: 'Hello! This is a text-to-speech test.',
  voice: 'alloy',
  response_format: 'mp3',
});

// Save the audio response to a file
const buffer = Buffer.from(await response.arrayBuffer());
await fs.promises.writeFile('output.mp3', buffer);
console.log('Audio saved to output.mp3');
```

**`OpenAI Python`**

```python title="OpenAI Python" lines
from openai import OpenAI

client = OpenAI(
  base_url="https://api.tramlabs.io/v1",
  api_key="{{API_KEY_REF}}",
)

with client.audio.speech.with_streaming_response.create(
  model="{{MODEL}}",
  input="Hello! This is a text-to-speech test.",
  voice="alloy",
  response_format="mp3"
) as response:
  response.stream_to_file("output.mp3")
```

**`Python 1`**

```python title="Python 1" expandable lines
import requests

response = requests.post(
  url="https://api.tramlabs.io/v1/audio/speech",
  headers={
    "Authorization": f"Bearer {API_KEY_REF}",
    "Content-Type": "application/json"
  },
  json={
    "model": "{{MODEL}}",
    "input": "Hello! This is a text-to-speech test.",
    "voice": "alloy",
    "response_format": "mp3"
  }
)
response.raise_for_status()

with open("output.mp3", "wb") as f:
  f.write(response.content)

generation_id = response.headers.get("X-Generation-Id")
print(f"Audio saved. Generation ID: {generation_id}")
```

**`TypeScript (fetch)`**

```typescript title="TypeScript (fetch)" expandable lines
const response = await fetch('https://api.tramlabs.io/v1/audio/speech', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${API_KEY_REF}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: '{{MODEL}}',
    input: 'Hello! This is a text-to-speech test.',
    voice: 'alloy',
    response_format: 'mp3',
  }),
});

if (!response.ok) {
  const err = await response.json();
  throw new Error(`TTS error ${response.status}: ${JSON.stringify(err)}`);
}

const audioBuffer = await response.arrayBuffer();
const generationId = response.headers.get('X-Generation-Id');
console.log(`Generation ID: ${generationId}`);
// Save audioBuffer to a file or play it directly
```

**`cURL`**

```bash title="cURL" lines
curl https://api.tramlabs.io/v1/audio/speech \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TRAM_AI_API_KEY" \
  --output output.mp3 \
  -d '{
    "model": "{{MODEL}}",
    "input": "Hello! This is a text-to-speech test.",
    "voice": "alloy",
    "response_format": "mp3"
  }'
```

### Tham số request

| Tham số           | Type   | Bắt buộc | Mô tả                                                                                                                                                  |
| ----------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `model`           | string | Có       | Model TTS cần dùng (ví dụ: `gpt-4o-mini-tts`, `Voxtral Mini TTS`)                                                                                      |
| `input`           | string | Có       | Văn bản cần tổng hợp thành giọng nói                                                                                                                   |
| `voice`           | string | Có       | Định danh giọng nói — xem bảng [Giọng nói theo provider](#giọng-nói-theo-provider) bên dưới                                                            |
| `response_format` | string | Không    | Định dạng âm thanh đầu ra: `mp3`, `pcm`, `opus`, `aac`, `flac`, `wav`. Mặc định là `pcm`. Xem bảng [Định dạng theo provider](#định-dạng-theo-provider) |
| `speed`           | number | Không    | Hệ số nhân tốc độ phát (`0.25` – `4.0`). Hỗ trợ bởi OpenAI, ElevenLabs. Bị bỏ qua bởi các provider khác. Mặc định là `1.0`                             |
| `provider`        | object | Không    | Cấu hình passthrough riêng theo provider                                                                                                               |

### Giọng nói theo provider

Trạm AI ánh xạ một tập giọng chuẩn sang từng provider. Người dùng có thể dùng tên chuẩn (cột trái) hoặc truyền thẳng voice ID gốc của provider.

#### OpenAI (`gpt-4o-mini-tts`)

| Voice     | Mô tả                    |
| --------- | ------------------------ |
| `alloy`   | Trung tính, cân bằng     |
| `ash`     | Ấm, tự nhiên             |
| `coral`   | Rõ ràng, thân thiện      |
| `echo`    | Nam, trầm                |
| `fable`   | Kể chuyện, biểu cảm      |
| `nova`    | Nữ, tươi sáng            |
| `onyx`    | Nam, sâu                 |
| `sage`    | Điềm tĩnh, chuyên nghiệp |
| `shimmer` | Nữ, nhẹ nhàng            |

> OpenAI TTS hỗ trợ thêm `instructions` qua [provider passthrough](#tùy-chọn-riêng-theo-provider).

#### ElevenLabs (`eleven_v3`, `eleven_flash_v2_5`)

| Voice (chuẩn) | Voice ID ElevenLabs    | Tên gốc |
| ------------- | ---------------------- | ------- |
| `alloy`       | `21m00Tcm4TlvDq8ikWAM` | Rachel  |
| `amber`       | `5Q0t7uMcjvnagumLfvZi` | Paul    |
| `ash`         | `AZnzlk1XvdvUeBnXmlld` | Domi    |
| `august`      | `D38z5RcWu1voky8WS1ja` | Fin     |
| `blue`        | `2EiwWnXFnvU5JabPnv8n` | Clyde   |
| `coral`       | `9BWtsMINqrJLrRacOk9x` | Aria    |
| `lily`        | `EXAVITQu4vr4xnSDxMaL` | Sarah   |
| `onyx`        | `29vD33N1CtxCmqQRPOHJ` | Drew    |
| `sage`        | `CwhRBWXzGAHq8TQ4Fs17` | Roger   |
| `verse`       | `CYw3kZ02Hs0563khs1Fj` | Dave    |

> Ngoài bảng trên, người dùng có thể truyền bất kỳ Voice ID nào từ [ElevenLabs Voice Library](https://elevenlabs.io/voice-library) vào trường `voice`.

### Định dạng theo provider

Không phải provider nào cũng hỗ trợ tất cả định dạng. Bảng dưới liệt kê các giá trị `response_format` được hỗ trợ:

| `response_format` | OpenAI | ElevenLabs |
| ----------------- | ------ | ---------- |
| `mp3`             | ✅      | ✅          |
| `pcm`             | ✅      | ✅          |
| `opus`            | ✅      | ✅          |
| `aac`             | ✅      | —          |
| `flac`            | ✅      | —          |
| `wav`             | ✅      | —          |

### Tùy chọn riêng theo provider

Người dùng có thể truyền các tùy chọn riêng theo provider bằng tham số `provider`. Tùy chọn được nhóm theo khóa là slug của provider, và chỉ tùy chọn của provider khớp mới được chuyển tiếp:

**`lines`**

```json lines
{
  "model": "gpt-4o-mini-tts",
  "input": "Hello world",
  "voice": "alloy",
  "provider": {
    "options": {
      "openai": {
        "instructions": "Speak in a warm, friendly tone."
      }
    }
  }
}
```

## Định dạng response

Endpoint TTS trả về một **byte stream âm thanh thô**, không phải JSON. Response sẽ kèm theo các header sau:

| Header            | Mô tả                                                                                     |
| ----------------- | ----------------------------------------------------------------------------------------- |
| `Content-Type`    | Kiểu MIME của âm thanh. `audio/mpeg` cho định dạng `mp3`, `audio/pcm` cho định dạng `pcm` |
| `X-Generation-Id` | ID sinh nội dung duy nhất cho request, hữu ích đối với việc theo dõi và debug             |

### Định dạng đầu ra

| Định dạng | Content-Type | Mô tả                                                                                       |
| --------- | ------------ | ------------------------------------------------------------------------------------------- |
| `mp3`     | `audio/mpeg` | Âm thanh nén, kích thước file nhỏ hơn. Phù hợp để lưu trữ và phát lại                       |
| `pcm`     | `audio/pcm`  | Âm thanh thô, không nén. Độ trễ thấp hơn, phù hợp cho các pipeline streaming thời gian thực |

## Giá

Các model TTS được tính giá **theo từng ký tự** của văn bản đầu vào. Mức giá khác nhau tùy model và provider. Người dùng có thể xem chi phí trên mỗi ký tự của từng model trên [trang Models](/tong-quan/models) hoặc qua Models API.

## Tương thích với OpenAI SDK

Endpoint TTS hoàn toàn tương thích với OpenAI SDK. Người dùng có thể dùng thư viện client của OpenAI bằng cách trỏ chúng tới base URL của Trạm AI:

**`OpenAI Python SDK`**

```python title="OpenAI Python SDK" expandable lines
from openai import OpenAI

client = OpenAI(
  base_url="https://api.tramlabs.io/v1",
  api_key="{{API_KEY_REF}}",
)

# Non-streaming: get the full audio response
response = client.audio.speech.create(
  model="gpt-4o-mini-tts",
  input="The quick brown fox jumps over the lazy dog.",
  voice="nova",
  response_format="mp3"
)
response.write_to_file("output.mp3")

# Streaming: process audio chunks as they arrive
with client.audio.speech.with_streaming_response.create(
  model="gpt-4o-mini-tts",
  input="The quick brown fox jumps over the lazy dog.",
  voice="nova",
  response_format="mp3"
) as response:
  response.stream_to_file("output.mp3")
```

**`OpenAI TypeScript`**

```typescript title="OpenAI TypeScript" lines
import OpenAI from 'openai';
import fs from 'fs';

const client = new OpenAI({
  baseURL: 'https://api.tramlabs.io/v1',
  apiKey: '{{API_KEY_REF}}',
});

const response = await client.audio.speech.create({
  model: 'gpt-4o-mini-tts',
  input: 'The quick brown fox jumps over the lazy dog.',
  voice: 'nova',
  response_format: 'mp3',
});

const buffer = Buffer.from(await response.arrayBuffer());
await fs.promises.writeFile('output.mp3', buffer);
console.log('Audio saved to output.mp3');
```

## Thực hành tốt nhất

* **Chọn đúng định dạng**: Dùng `mp3` để lưu trữ và phát lại thông thường. Dùng `pcm` cho các pipeline streaming thời gian thực, nơi độ trễ là yếu tố quan trọng
* **Lựa chọn giọng nói**: Mỗi provider cung cấp một bộ giọng khác nhau. Hãy xem tài liệu của model hoặc thử qua các giọng khả dụng để tìm giọng phù hợp nhất.
* **Độ dài đầu vào**: Với những văn bản rất dài, hãy cân nhắc chia đầu vào thành các đoạn nhỏ hơn rồi nối các đoạn âm thanh đầu ra lại. Cách này giúp cải thiện độ tin cậy và giảm độ trễ cho đoạn âm thanh đầu tiên
* **Tham số speed**: Tham số `speed` chỉ được một số provider hỗ trợ (ví dụ: OpenAI). Các provider không hỗ trợ sẽ âm thầm bỏ qua tham số này

## Khắc phục sự cố

**File âm thanh trống hoặc bị hỏng?**

* Kiểm tra `response_format` có khớp với cách lưu file hay không (ví dụ: đừng lưu đầu ra `pcm` với phần mở rộng `.mp3`)
* Kiểm tra mã trạng thái của response — response không phải 200 sẽ trả về phần thân lỗi dạng JSON chứ không phải âm thanh

**Không tìm thấy model?**

* Dùng [trang Models](/tong-quan/models) để tìm các model TTS khả dụng
* Kiểm tra slug của model có chính xác hay không (ví dụ: `gpt-4o-mini-tts`, không phải `gpt-4o-mini-tts`)

**Giọng nói không khả dụng?**

* Các giọng khả dụng khác nhau tùy provider. Hãy xem tài liệu của provider để biết các định danh giọng nói được hỗ trợ
* Mỗi model đều có bộ giọng riêng — hãy xem trang của model trên [trang Models](/tong-quan/models) để biết danh sách đầy đủ