# Streaming API

### Tóm tắt luồng hoạt động

1. Kết nối WebSocket
2. Gửi cấu hình khởi tạo
3. Xác nhận từ hệ thống
4. Gửi dữ liệu âm thanh liên tục
5. Nhận kết quả theo thời gian thực
6. Thông báo khi hoàn tất gửi audio
7. Nhận kết quả cuối và kết thúc

### **Bước 1: Kết nối WebSocket**

Client tạo kết nối WebSocket với API:

wss\://api.vbee.vn/v1/stt/realtime?token=\<token>\&appId=\<app-id>

Nếu token không hợp lệ → kết nối sẽ bị đóng ngay.

Nếu hợp lệ: Server xác thực token (tự động)

### **Bước 2: Gửi cấu hình khởi tạo (StreamingConfig)**

Sau khi kết nối thành công, client bắt buộc gửi 1 message cấu hình bao gồm các tham số:

| **Tham số**                       | **Kiểu dữ liệu** | **Tính bắt buộc** | **Mô tả**                                                               |
| --------------------------------- | ---------------- | ----------------- | ----------------------------------------------------------------------- |
| sampleRateHertz                   | integer          | Có                | Tần số lấy mẫu (8000 hoặc 16000 Hz)                                     |
| sampleSizeByte                    | integer          | Có                | Số byte mỗi sample (luôn = 2)                                           |
| channel                           | integer          | Có                | Số kênh (chỉ hỗ trợ 1 – mono)                                           |
| interimResults                    | boolean          | Không             | <p>Nhận kết quả tạm thời khi đang nói</p><p>Giá trị mặc định: false</p> |
| sessionId                         | string           | Không             | Session ID tự đặt để tracking/debug                                     |
| vadConfig.noInputTimeoutMs        | integer          | <p>Không<br></p>  | Timeout (ms) nếu không phát hiện âm thanh. Range: `3000–10000`          |
| vadConfig.speechCompleteTimeoutMs | integer          | Không             | Thời gian im lặng (ms) để xác định hết câu. Range: `500–3000`           |

Sau khi gửi config, cần chờ server trả về READY rồi mới gửi audio.

### **Bước 3: Xác nhận từ hệ thống (READY)**

Server trả về sau khi sẵn sàng nhận audio:

{

&#x20;"type": "READY",

&#x20;"sessionId": "abc123"

}

### **Bước 4: Gửi dữ liệu âm thanh liên tục (AudioChunk)**

Client gửi audio liên tục dưới dạng chunk:

{

&#x20;"type": "AudioChunk",

&#x20;"audioContent": "\<base64-audio>"

}

Yêu cầu audio:

* Format: Raw PCM (không có WAV header)
* 16-bit, mono
* Sample rate phải khớp với config

Khuyến nghị:

* Gửi mỗi 80–100ms audio / lần
* Gửi đều để đảm bảo chất lượng nhận dạng

### **Bước 5: Nhận kết quả theo thời gian thực**

**5.1. Kết quả tạm thời (InterimResult)**

Kết quả trả về trong lúc người dùng đang nói, có thể thay đổi liên tục và không phải kết quả cuối cùng.

Các kết quả nhận được như sau:

| **Tham số**    | **Kiểu dữ liệu** | **Mô tả**                                         |
| -------------- | ---------------- | ------------------------------------------------- |
| text           | string           | Văn bản tạm thời, sẽ thay đổi ở interim tiếp theo |
| isFinal        | boolean          | Luôn là false                                     |
| stability      | float            | Mức độ ổn định 0.0–1.0. Cao = ít thay đổi hơn     |
| startTime      | float            | Thời điểm bắt đầu utterance (giây) trong stream   |
| endTime        | float            | Thời điểm kết thúc tạm thời (giây) — tăng dần     |
| startVoiceTime | float            | Thời điểm phát hiện giọng nói bắt đầu             |
| endVoiceTime   | float            | Thời điểm phát hiện giọng nói kết thúc tạm thời   |

**5.2. Kết quả chính thức (FinalResult)**

Kết quả trả về khi kết thúc một câu, là kết quả cuối cùng và không thay đổi.

Các kết quả nhận được như sau:

| **Tham số**     | **Kiểu dữ liệu** | **Mô tả**                                                                              |
| --------------- | ---------------- | -------------------------------------------------------------------------------------- |
| text            | string           | Văn bản chính thức, đã qua hậu xử lý                                                   |
| textRaw         | string           | Văn bản thô chưa xử lý                                                                 |
| isFinal         | boolean          | Luôn là true                                                                           |
| confidenceScore | float            | Độ tin cậy 0.0 – 1.0                                                                   |
| startTime       | float            | Thời điểm bắt đầu utterance (giây)                                                     |
| endTime         | float            | Thời điểm kết thúc tạm thời (giây)                                                     |
| speechType      | string           | <ul><li>detected-speech: có tiếng nói </li><li>no-speech: không có tiếng nói</li></ul> |
| status          | string           | SUCCESS hoặc FAILURE                                                                   |

### **Bước 6: Thông báo khi hoàn tất gửi audio (DONE)**

Gửi sau khi truyền hết toàn bộ audio

{

&#x20; "type": "Done"

}

### **Bước 7: Nhận kết quả cuối và kết thúc (StreamEnd)**&#x20;

Gửi sau khi server xử lý xong Done signal và đã gửi FinalResult cuối. Server sẽ đóng kết nối sau message này.

```
{
  "type": "STREAM_END",
  "sessionId": "srv-session-abc123",
  "totalUtterances": 4
}
```

* sessionId: Session ID của session vừa kết thúc
* totalWords: Tổng số utterance đã nhận dạng trong session

Khi session vượt quá 90 giây sẽ nhận được:

* type: ERROR
* code: SESSION\_TIMEOUT
* message: Session exceeded maximum duration

**Danh sách mã lỗi:**

<table data-header-hidden><thead><tr><th></th><th width="165"></th><th width="96"></th><th></th></tr></thead><tbody><tr><td><strong>code</strong></td><td><strong>Giai đoạn</strong></td><td><strong>retryable</strong></td><td><strong>Mô tả</strong></td></tr><tr><td>UNAUTHORIZED</td><td>AUTHENTICATING</td><td>false</td><td>Token không hợp lệ hoặc hết hạn</td></tr><tr><td>STT_INSUFFICIENT_SECONDS</td><td>AUTHENTICATING</td><td>false</td><td>Không đủ số giây trong tài khoản</td></tr><tr><td>STT_MAX_CCR_REACHED</td><td>AUTHENTICATING</td><td>true</td><td>Đã đạt giới hạn concurrent session</td></tr><tr><td>STT_INVALID_SAMPLE_RATE</td><td>CONFIGURING</td><td>false</td><td>sampleRateHertz không phải 8000 hoặc 16000</td></tr><tr><td>STT_INVALID_CHANNEL</td><td>CONFIGURING</td><td>false</td><td>channel không phải 1</td></tr><tr><td>STT_INVALID_SAMPLE_SIZE</td><td>CONFIGURING</td><td>false</td><td>sampleSizeByte không phải 2 (16-bit PCM)</td></tr><tr><td>PROVIDER_UNAVAILABLE</td><td>CONFIGURING / STREAMING</td><td>true</td><td>Provider không phản hồi hoặc lỗi tạm thời</td></tr><tr><td>PROVIDER_UNKNOWN</td><td>CONFIGURING / STREAMING</td><td>false</td><td>Provider trả về lỗi không xác định / không ánh xạ được</td></tr><tr><td>SESSION_TIMEOUT</td><td>STREAMING</td><td>false</td><td>Session vượt quá 90 giây</td></tr><tr><td>NO_INPUT_TIMEOUT</td><td>STREAMING</td><td>false</td><td>Không phát hiện âm thanh trong noInputTimeoutMs</td></tr><tr><td>RECOGNIZE_FAILED</td><td>Recognize</td><td>true</td><td>Recognize job thất bại ở provider (thường gặp ở async)</td></tr><tr><td>JOB_NOT_FOUND</td><td>Recognize</td><td>false</td><td>Không tìm thấy transcriptId khi poll /v1/stt/transcripts/:id</td></tr><tr><td>INTERNAL_ERROR</td><td>Bất kỳ</td><td>true</td><td>Lỗi nội bộ không xác định</td></tr></tbody></table>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://api-docs.vbee.vn/vbee-api/speech-to-text/streaming-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
