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

# Speech-to-Text

> Cách chuyển âm thanh thành văn bản với các model của Trạm AI

Trạm AI hỗ trợ speech-to-text (STT) qua một endpoint chuyên dụng `/v1/audio/transcriptions`. Người dùng gửi âm thanh đã mã hóa base64 và nhận về một response JSON gồm văn bản đã chuyển cùng thống kê sử dụng.

## Tìm kiếm model

Có thể tìm các model STT 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à `"transcription"`:

**`lines`**

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

# Tìm model STT: lọc các model có mode = "transcription"
```

### Trên trang Models

Truy cập [trang Models](/tong-quan/models) rồi lọc theo output modality để tìm các model có khả năng transcribe âm thanh. Bạn cũng có thể duyệt [bộ sưu tập Speech-to-Text](/collections/speech-to-text-models) để xem một danh sách được chọn lọc sẵn.

## Sử dụng API

Gửi một request `POST` đến `/v1/audio/transcriptions` với body JSON chứa âm thanh đã mã hóa base64. Response trả về là JSON gồm văn bản đã chuyển và thống kê sử dụng tùy chọn.

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

**`TypeScript`**

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

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

const audioBuffer = await fs.promises.readFile('audio.wav');
const base64Audio = audioBuffer.toString('base64');

const result = await fetch('https://api.tramlabs.io/v1/audio/transcriptions', {
  method: 'POST',
  headers: {
    Authorization: `Bearer {{API_KEY_REF}}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: '{{MODEL}}',
    input_audio: {
      data: base64Audio,
      format: 'wav',
    },
  }),
});

const data = await result.json();
console.log(data.text);
```

**`Python`**

```python title="Python" expandable lines
import requests
import base64
import json

with open("audio.wav", "rb") as f:
    base64_audio = base64.b64encode(f.read()).decode("utf-8")

response = requests.post(
    url="https://api.tramlabs.io/v1/audio/transcriptions",
    headers={
        "Authorization": "Bearer {{API_KEY_REF}}",
        "Content-Type": "application/json"
    },
    data=json.dumps({
        "model": "{{MODEL}}",
        "input_audio": {
            "data": base64_audio,
            "format": "wav"
        }
    })
)

result = response.json()
print(result["text"])
```

**`TypeScript (fetch)`**

```typescript title="TypeScript (fetch)" expandable lines
import fs from 'fs';

const audioBuffer = await fs.promises.readFile('audio.wav');
const base64Audio = audioBuffer.toString('base64');

const response = await fetch('https://api.tramlabs.io/v1/audio/transcriptions', {
  method: 'POST',
  headers: {
    Authorization: `Bearer {{API_KEY_REF}}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: '{{MODEL}}',
    input_audio: {
      data: base64Audio,
      format: 'wav',
    },
  }),
});

const result = await response.json();
console.log(result.text);
```

**`cURL`**

```bash title="cURL" lines
# Base64-encode your audio file
AUDIO_BASE64=$(base64 < audio.wav | tr -d '\n')

curl https://api.tramlabs.io/v1/audio/transcriptions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TRAM_AI_API_KEY" \
  -d '{
    "model": "{{MODEL}}",
    "input_audio": {
      "data": "'"$AUDIO_BASE64"'",
      "format": "wav"
    }
  }'
```

### Tham số request

| Tham số              | Kiểu   | Bắt buộc | Mô tả                                                                           |
| -------------------- | ------ | -------- | ------------------------------------------------------------------------------- |
| `model`              | string | Có       | Model STT cần dùng (ví dụ: `elevenlabs-scribe-v1`)                              |
| `input_audio`        | object | Có       | Dữ liệu âm thanh cần transcribe                                                 |
| `input_audio.data`   | string | Có       | Dữ liệu âm thanh mã hóa base64 (raw bytes, không phải data URI)                 |
| `input_audio.format` | string | Có       | Định dạng âm thanh (ví dụ: `wav`, `mp3`, `flac`, `m4a`, `ogg`, `webm`, `aac`)   |
| `language`           | string | Không    | Mã ngôn ngữ ISO-639-1 (ví dụ: `"en"`, `"ja"`). Tự động nhận diện nếu bỏ trống   |
| `temperature`        | number | Không    | Nhiệt độ lấy mẫu trong khoảng 0 đến 1. Giá trị thấp hơn cho kết quả ổn định hơn |
| `provider`           | object | Không    | Cấu hình passthrough riêng cho từng provider                                    |

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

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

**`lines`**

```json lines
{
  "model": "Whisper Large V3",
  "input_audio": {
    "data": "UklGRiQA...",
    "format": "wav"
  },
  "provider": {
    "options": {
      "groq": {
        "prompt": "Expected vocabulary: Tram AI, API, transcription"
      }
    }
  }
}
```

## Định dạng response

Endpoint STT trả về một response JSON chứa văn bản đã chuyển:

**`lines`**

```json lines
{
  "text": "Hello, this is a test of speech-to-text transcription.",
  "usage": {
    "seconds": 9.2,
    "total_tokens": 113,
    "input_tokens": 83,
    "output_tokens": 30,
    "cost": 0.000508
  }
}
```

### Trường trong response

| Trường                | Kiểu   | Mô tả                                      |
| --------------------- | ------ | ------------------------------------------ |
| `text`                | string | Văn bản đã chuyển                          |
| `usage.seconds`       | number | Thời lượng âm thanh đầu vào tính bằng giây |
| `usage.total_tokens`  | number | Tổng số token đã dùng (input + output)     |
| `usage.input_tokens`  | number | Số input token được tính phí               |
| `usage.output_tokens` | number | Số output token được tạo ra                |
| `usage.cost`          | number | Tổng chi phí của request tính bằng USD     |

### Response header

| Header            | Mô tả                                                            |
| ----------------- | ---------------------------------------------------------------- |
| `X-Generation-Id` | ID generation duy nhất của request, hữu ích để theo dõi và debug |

## Định dạng âm thanh được hỗ trợ

Các định dạng âm thanh được hỗ trợ khác nhau tùy provider. Một số định dạng phổ biến gồm:

| Định dạng | MIME Type    | Mô tả                                                    |
| --------- | ------------ | -------------------------------------------------------- |
| `wav`     | `audio/wav`  | Âm thanh không nén, chất lượng cao nhất                  |
| `mp3`     | `audio/mpeg` | Âm thanh nén, tương thích tốt trên mọi nền tảng          |
| `flac`    | `audio/flac` | Âm thanh nén không mất dữ liệu                           |
| `m4a`     | `audio/mp4`  | Âm thanh MPEG-4                                          |
| `ogg`     | `audio/ogg`  | Âm thanh Ogg Vorbis                                      |
| `webm`    | `audio/webm` | Âm thanh WebM, phổ biến trong các bản ghi từ trình duyệt |
| `aac`     | `audio/aac`  | Advanced Audio Coding                                    |

## Định giá

Các model STT áp dụng những cách định giá khác nhau tùy theo provider:

* **Theo thời lượng** (ví dụ: OpenAI Whisper): Tính phí theo mỗi giây âm thanh đầu vào
* **Theo token** (ví dụ: các model OpenAI mới hơn): Tính phí theo mỗi input/output token, tương tự các model văn bản

Người dùng có thể xem chi phí của từng model trên [trang Models](/tong-quan/models) hoặc qua Models API. Trường `usage.cost` trong response cho biết chi phí thực tế của mỗi request.

## BYOK (Bring Your Own Key)

STT hỗ trợ [BYOK](/tong-quan/auth/byok), cho phép dùng chính API key của provider đang có. Khi đã cấu hình, request sẽ được route thẳng đến provider bằng key của người dùng, và Trạm AI chỉ tính phí nền tảng thay vì chi phí model theo mức sử dụng.

## Playground

Hãy thử nghiệm các model STT ngay trên trình duyệt bằng [Trạm AI Chat](https://chat.tramlabs.io). Mở trang của bất kỳ model STT nào, rồi tải lên một file âm thanh và xem kết quả transcribe.

## Khác biệt so với Audio Input

Trạm AI hỗ trợ hai cách xử lý âm thanh:

1. **Speech-to-Text** (trang này): Một endpoint chuyên dụng `/v1/audio/transcriptions` được tối ưu riêng cho việc transcribe. Endpoint này trả về JSON có cấu trúc gồm văn bản đã chuyển và dữ liệu sử dụng. Phù hợp nhất để chuyển âm thanh thành văn bản.
2. **Audio input qua Chat Completions** ([tài liệu Audio](/tong-quan/multimodal/audio)): Gửi âm thanh như một phần của request `/v1/chat/completions` với content type `input_audio`. Model sẽ xử lý âm thanh cùng với văn bản và trả lời theo dạng hội thoại. Phù hợp nhất để phân tích âm thanh, trả lời câu hỏi về nội dung âm thanh, hoặc kết hợp âm thanh với các modality khác.

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

* **Chọn đúng định dạng**: WAV cho chất lượng tốt nhất khi transcribe. MP3 và các định dạng nén khác hoạt động tốt nhưng có thể giảm nhẹ độ chính xác với những đoạn âm thanh khó nghe
* **Kích thước file**: Với các file âm thanh rất dài, hãy cân nhắc chia nhỏ thành nhiều đoạn. Giới hạn timeout phía provider là 60 giây, nên các file quá lớn có thể bị timeout
* **Mã hóa base64**: Âm thanh phải được gửi dưới dạng dữ liệu mã hóa base64 (raw bytes, không phải data URI). Hầu hết các ngôn ngữ lập trình đều có sẵn công cụ để mã hóa base64

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

**Transcription rỗng hoặc không chính xác?**

* Kiểm tra xem định dạng âm thanh có khớp với trường `format` trong request không
* Đảm bảo chất lượng âm thanh đủ tốt để transcribe

**Request bị timeout?**

* Các file âm thanh lớn có thể vượt quá giới hạn timeout 60 giây. Hãy chia các bản ghi dài thành nhiều đoạn nhỏ hơn
* Các định dạng nén (MP3, AAC) tạo ra payload nhỏ hơn và truyền nhanh hơn

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

* Dùng [trang Models](/tong-quan/models) hoặc [Public Models API](/tong-quan/models#public-models-api-publicmodels) để tìm các model STT khả dụng (lọc theo `mode: "transcription"`)
* Kiểm tra xem model slug có chính xác không (ví dụ: `elevenlabs-scribe-v1`, không phải `whisper-1`)

**Lỗi xác thực?**

* Hãy đảm bảo API key đang dùng là hợp lệ từ [dashboard Trạm AI](https://console.tramlabs.io/keys)
* Endpoint STT dùng cùng cơ chế xác thực với Chat Completions API