Rest Api
Note: The URL used in this document (
vas-poc.vurbo.ai) is the planned deployment URL. A separate notice will be provided once the service goes live.
Table of Contents
- REST API
- Table of Contents
- API Overview
- GET /api/v1/tasks (List Tasks)
- DELETE /api/v1/tasks/{taskId} (Delete Task)
- PUT /api/v1/tasks/batch/pin (Batch Update Pin Status)
- DELETE /api/v1/tasks/batch (Batch Delete Tasks)
- PUT /api/v1/tasks/{taskId}/pin (Update Pin Status)
- PUT /api/v1/tasks/{taskId}/read (Mark as Read)
- PATCH /api/v1/tasks/{taskId}/name (Update Task Name)
- GET /api/v1/tasks/{taskId}/audio/export (Download Task Audio)
- GET /api/v1/tasks/{taskId}/transcript/export (Download Transcript)
- POST /api/v1/tasks/{taskId}/force-fail (Force Mark as Failed)
- POST /api/v1/tasks/{taskId}/retry (Reprocess Failed Task)
- Audio Import API
- Audio API
- TTS API
- Broadcasts API
- Viewer API
- Recording Speaker Editing API
- Summary Template API
- Generate Summary API (Bearer Authentication)
- Error Handling
API Overview
| Item | Value |
|---|---|
| Base Path | https://vas-poc.vurbo.ai/api/v1 |
| Protocol | HTTPS |
| Data Format | JSON |
Authentication
APIs that require authentication pass the API Key via an HTTP header:
X-API-Key: vas_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
API Categories
| Category | Path Prefix | Authentication | Purpose |
|---|---|---|---|
| Tasks API | /api/v1/tasks | Header X-API-Key | Task management, audio/transcript export |
| Import API | /api/v1/imports | Header X-API-Key | Audio import |
| Audio API | /api/v1/sse/audio | Header X-API-Key | Audio file playback |
| TTS API | /api/v1/tts | Header X-API-Key | TTS voice service |
| Broadcasts API | /api/v1/broadcasts | Header X-API-Key | Broadcast management |
| Viewer API | /api/v1/viewer/broadcasts | None | Viewer-side public info |
| Recording Speaker API | /api/v1/tasks/{taskId}/speakers | Header X-API-Key | Transcript speaker editing (since V1.4.1 the recordings path is a deprecated alias, removed in V1.6.0) |
| Summary Template API | /api/v1/summary-templates | Header X-API-Key | Summary template lookup |
| Generate Summary API | /api/v1/summary | Header Authorization: Bearer | Generate a summary for any transcript (Bearer authentication) |
| Broadcast REST API | /broadcast | Token (path parameter) | Broadcast real-time status |
GET /api/v1/tasks (List Tasks)
Description
Retrieve the recording task list for the current user. You can use the status parameter to filter tasks by processing stage.
Use Cases
- Display the task history list
- View completed recordings
- Query in-progress recording tasks
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters (Query)
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
status | string | No | completed | Filter task status: completed, active, all |
| status Value | Description |
|---|---|
completed | Return only completed tasks (default, backward compatible) |
active | Return in-progress tasks (recording, importing, uploading, processing) |
all | Return all tasks without filtering by status |
Request Example
# Default query (completed tasks)
curl -X GET "https://vas-poc.vurbo.ai/api/v1/tasks" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
# Query in-progress tasks
curl -X GET "https://vas-poc.vurbo.ai/api/v1/tasks?status=active" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
Success Response
| Field | Type | Description |
|---|---|---|
data.tasks | array | Task list |
data.tasks[].task_id | string | Task ID (UUID) |
data.tasks[].title | string | Task title |
data.tasks[].type | string | Recording type |
data.tasks[].type_source | string | Source type (realtime / import / broadcast) |
data.tasks[].duration_ms | number | Recording duration (milliseconds) |
data.tasks[].duration_formatted | string | Formatted duration (min:sec) |
data.tasks[].transcription_languages | array | Transcription language list |
data.tasks[].translation_languages | array | Translation language list |
data.tasks[].created_at | string | Creation time (ISO 8601) |
data.tasks[].processing_status | string | Processing status |
data.tasks[].is_pinned | boolean | Whether pinned |
data.tasks[].is_unread | boolean | Whether unread |
processing_status Values
| Status | Description | Applicable Scenario |
|---|---|---|
recording | Recording in progress | Real-time recording, broadcast |
importing | Audio import in progress | Audio import |
uploading | Uploading to the cloud | Upload phase after recording stops |
processing | Post-processing | Summary, translation, etc. |
completed | Processing complete | All scenarios |
failed | Processing failed | All scenarios |
Response Example
{
"data": {
"tasks": [
{
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Meeting Notes",
"type": "transcribe",
"type_source": "realtime",
"duration_ms": 60000,
"duration_formatted": "1:00",
"transcription_languages": ["zh-TW"],
"translation_languages": ["en-US"],
"created_at": "2026-02-25T10:00:00Z",
"processing_status": "completed",
"is_pinned": false,
"is_unread": true
}
]
}
}
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
auth_missing_api_key | 401 | API Key not provided | Make sure the header includes the API Key |
auth_invalid_api_key | 401 | Invalid API Key | Verify that the API Key is correct |
DELETE /api/v1/tasks/{taskId} (Delete Task)
Description
Delete the specified task (soft delete). After deletion, the task will no longer appear in the list.
Use Cases
- Clear recording records you no longer need
- Organize the task list
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
taskId | string | Yes | Task ID (UUID) |
Request Example
curl -X DELETE "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
Success Response
{
"message": "Task deleted"
}
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
recording_not_found | 404 | The specified recording was not found | Verify that taskId is correct |
recording_unauthorized | 403 | Not authorized to operate on this recording | Confirm the task belongs to the user |
PUT /api/v1/tasks/batch/pin (Batch Update Pin Status)
Description
Batch update the pin status of multiple tasks. Up to 100 tasks can be operated on per request. Only tasks belonging to the current user are affected; IDs that do not belong to the user are ignored.
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Location | Type | Required | Description |
|---|---|---|---|---|
task_ids | body | array | Yes | Array of task IDs (each element a UUID, up to 100) |
is_pinned | body | boolean | Yes | Pin status |
Request Example
curl -X PUT "https://vas-poc.vurbo.ai/api/v1/tasks/batch/pin" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{
"task_ids": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
],
"is_pinned": true
}'
Success Response
{
"data": {
"affected_count": 2
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
data.affected_count | number | Number of tasks actually updated |
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
validation_failed | 422 | Parameter validation failed | Make sure task_ids is an array of UUIDs with no more than 100 entries, and is_pinned is a boolean |
DELETE /api/v1/tasks/batch (Batch Delete Tasks)
Description
Batch delete multiple tasks (soft delete). Up to 100 tasks can be operated on per request. Only tasks belonging to the current user are affected; IDs that do not belong to the user are ignored.
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Location | Type | Required | Description |
|---|---|---|---|---|
task_ids | body | array | Yes | Array of task IDs (each element a UUID, up to 100) |
Request Example
curl -X DELETE "https://vas-poc.vurbo.ai/api/v1/tasks/batch" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{
"task_ids": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
]
}'
Success Response
{
"data": {
"affected_count": 2
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
data.affected_count | number | Number of tasks actually deleted |
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
validation_failed | 422 | Parameter validation failed | Make sure task_ids is an array of UUIDs with no more than 100 entries |
PUT /api/v1/tasks/{taskId}/pin (Update Pin Status)
Description
Update the pin status of a task. Pinned tasks are displayed first in the list.
Use Cases
- Mark important recordings
- Quickly access frequently used tasks
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
taskId | string | Yes | Task ID (path parameter) |
is_pinned | boolean | Yes | Pin status |
Request Example
curl -X PUT "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/pin" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{"is_pinned": true}'
Success Response
{
"is_pinned": true
}
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
recording_not_found | 404 | The specified recording was not found | Verify that taskId is correct |
validation_failed | 422 | Parameter validation failed | Make sure is_pinned is a boolean |
PUT /api/v1/tasks/{taskId}/read (Mark as Read)
Description
Mark a task as read.
Use Cases
- Mark recordings you have viewed
- Clear the unread indicator
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
taskId | string | Yes | Task ID (path parameter) |
Request Example
curl -X PUT "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/read" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
Success Response
{
"is_unread": false
}
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
recording_not_found | 404 | The specified recording was not found | Verify that taskId is correct |
PATCH /api/v1/tasks/{taskId}/name (Update Task Name)
Description
Update the name of the specified task.
Use Cases
- Customize the recording title
- Correct an automatically generated name
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
taskId | string | Yes | Task ID (path parameter) |
name | string | Yes | Task name (max 60 characters) |
Request Example
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/name" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{"name": "Product Meeting Discussion"}'
Success Response
{
"message": "Recording name updated",
"data": {
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Product Meeting Discussion",
"name_source": "user"
}
}
| Field | Type | Description |
|---|---|---|
name_source | string | Name source: default, llm, user |
Name Source Explanation:
| name_source | Description | Trigger Condition |
|---|---|---|
user | A name explicitly set by the user | set_name, this REST API (the system will not override it) |
llm | Automatically generated by the system from the transcript | At the end of a recording, if name_source is not user, the system generates one automatically |
default | Default name | The name passed to start (initial default, the system may still override it) or type + sequence number (e.g. Transcription #1) |
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
recording_not_found | 404 | The specified recording was not found | Verify that taskId is correct |
recording_unauthorized | 403 | Not authorized to operate on this recording | Confirm the task belongs to the user |
validation_failed | 422 | Validation failed | Make sure name is not empty and its length is valid |
GET /api/v1/tasks/{taskId}/audio/export (Download Task Audio)
Description
Download the original audio file of the specified task. The response is a binary audio stream with a Content-Disposition: attachment header, so a browser or download tool saves the content directly as a file. The file name uses the recording name first (a sanitized file name); if the name is empty, it falls back to audio.
Difference from the audio streaming API (
GET /api/v1/sse/audio/{taskId}):
- This endpoint: for offline download; the response includes a
Content-Disposition: attachmentheader; Range Requests are not supported.- Audio streaming: for playback; supports HTTP Range Requests for seeking/fast-forward; the response does not force a download.
Use Cases
- Save recording files offline
- Batch export the original audio of all tasks
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Location | Type | Required | Description |
|---|---|---|---|---|
taskId | path | string | Yes | Task ID (UUID) |
Request Example
curl -X GET "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/audio/export" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-OJ
Tip:
curl -OJlets curl automatically name the saved file based on the server'sContent-Dispositionresponse.
Success Response
HTTP 200
HTTP/1.1 200 OK
Content-Type: audio/mp4
Content-Length: 1234567
Content-Disposition: attachment; filename="audio.m4a"; filename*=UTF-8''%E6%9C%83%E8%AD%B0%E8%A8%98%E9%8C%84.m4a
Cache-Control: no-cache
Note: All recording audio files are returned as an M4A container (AAC encoding).
Content-Typeis fixed toaudio/mp4, and the file extension is.m4a.
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
recording_not_found | 404 | The specified recording was not found, or the audio file does not exist in cloud storage | Verify that taskId is correct and the recording has not been deleted |
recording_audio_not_ready | 422 | The audio file has not finished uploading or is still processing | Retry later; first confirm via GET /api/v1/tasks that processing_status is completed |
storage_download_failed | 500 | Storage service download failed | Retry later; if it keeps failing, contact support |
GET /api/v1/tasks/{taskId}/transcript/export (Download Transcript)
Description
Download the transcript of the specified task, supporting five formats: plain text, SubRip subtitles, YouTube SBV subtitles, WebVTT subtitles, and CSV spreadsheet. The response includes the original text and all translation languages; the response includes a Content-Disposition: attachment header for direct download. The file name uses the recording name first (a sanitized file name); if the name is empty, it falls back to transcript, and a -transcript.{ext} suffix is always appended.
Difference from the transcript history SSE API (
GET /api/v1/sse/history/transcribe/{taskId}):
- This endpoint: for offline download; returns the complete file at once; can be opened directly in subtitle software or a spreadsheet.
- SSE history API: for progressive loading; pushes raw structured data sentence by sentence as an event stream (JSON fragments) for progressive rendering in the frontend UI.
Use Cases
- Download the transcript for subtitle software (SRT / SBV / VTT)
- Export CSV to open in Excel or data analysis tools
- Save the plain-text transcript offline
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Location | Type | Required | Default | Description |
|---|---|---|---|---|---|
taskId | path | string | Yes | — | Task ID (UUID) |
format | query | string | No | txt | Format: txt / srt / sbv / vtt / csv |
format Explanation
| Format | Time Format | Content Structure | Typical Use |
|---|---|---|---|
txt | — | One line per segment, [Speaker] original text; translations indented 4 spaces as [language code] translated text | Reading, record keeping |
srt | HH:MM:SS,mmm | Includes a sequence number; after the time axis of each segment, the original text and translation each occupy one line | SubRip subtitles (DaVinci Resolve, VLC, etc.) |
sbv | H:MM:SS.mmm | No sequence number; the time axis is separated by ,; the original text and translation are joined with | into a single line (line breaks are replaced with spaces) | YouTube subtitle upload |
vtt | HH:MM:SS.mmm | Uses WEBVTT as the header; after the time axis of each segment, the original text and translation each occupy one line | HTML5 <track> subtitles, web players |
csv | HH:MM:SS (no milliseconds) | Begins with a UTF-8 BOM; columns index,start,end,speaker,text,<one column per translation language> | Excel, data analysis |
Request Example
# Default TXT format
curl -X GET "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/transcript/export" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-OJ
# Specify SRT format
curl -X GET "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/transcript/export?format=srt" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-OJ
# CSV (Excel can open it directly; the UTF-8 BOM ensures non-ASCII text is not garbled)
curl -X GET "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/transcript/export?format=csv" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-OJ
Success Response
HTTP 200
HTTP/1.1 200 OK
Content-Type: text/csv; charset=UTF-8
Content-Length: 2048
Content-Disposition: attachment; filename="transcript.csv"; filename*=UTF-8''%E6%9C%83%E8%AD%B0%E8%A8%98%E9%8C%84-transcript.csv
Cache-Control: no-cache
Note:
Content-Typeis determined dynamically based on theformatparameter:
Format Content-Type txttext/plain; charset=UTF-8srtapplication/x-subripsbvtext/plain; charset=UTF-8vtttext/vtt; charset=UTF-8csvtext/csv; charset=UTF-8
Output Example
Assume the transcript contains two segments of English audio (en-US) and two translations (zh-TW, ja-JP):
TXT
[Alice] Hello, good morning
[zh-TW] 你好,早安
[ja-JP] おはよう
[Bob] Thanks
[zh-TW] 多謝
[ja-JP] ありがとう
SRT
1
00:00:00,500 --> 00:00:03,000
Hello, good morning
你好,早安
おはよう
2
00:00:03,000 --> 00:00:04,200
Thanks
多謝
ありがとう
SBV
0:00:00.500,0:00:03.000
Hello, good morning | 你好,早安 | おはよう
0:00:03.000,0:00:04.200
Thanks | 多謝 | ありがとう
VTT
WEBVTT
00:00:00.500 --> 00:00:03.000
Hello, good morning
你好,早安
おはよう
00:00:03.000 --> 00:00:04.200
Thanks
多謝
ありがとう
CSV (the file begins with a UTF-8 BOM EF BB BF)
index,start,end,speaker,text,zh-TW,ja-JP
1,00:00:00,00:00:03,Alice,"Hello, good morning",你好,早安,おはよう
2,00:00:03,00:00:04,Bob,Thanks,多謝,ありがとう
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
recording_not_found | 404 | The specified recording was not found | Verify that taskId is correct and the recording has not been deleted |
recording_transcript_not_ready | 422 | The transcript has not finished generating or is empty | First confirm via GET /api/v1/tasks that processing_status = completed, then call again |
validation_failed | 422 | Parameter validation failed | Make sure format is one of the allowed values (txt / srt / sbv / vtt / csv) |
storage_download_failed | 500 | Storage service download failed | Retry later; if it keeps failing, contact support |
POST /api/v1/tasks/{taskId}/force-fail (Force Mark as Failed)
Description
Force a task that is stuck in a non-terminal state (recording / importing / uploading / pending / processing) to be marked as failed. After a successful operation, processing_status becomes failed, processing_error is set to the reason provided by the user, and a recording.failed webhook is triggered (payload.failure_source = user_forced). Tasks already in a terminal state (completed / failed) will receive a 422.
For the full specification and frontend example, see: Tasks API — POST force-fail.
Authentication
Header: X-API-Key.
Request Parameters
| Parameter | Location | Type | Required | Description |
|---|---|---|---|---|
taskId | path | string | Yes | Task ID (UUID) |
reason | body | string | null | No | Failure reason, up to 500 characters |
Request Example
curl -X POST "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/force-fail" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{"reason": "The recording client was disconnected too long; giving up waiting"}'
Success Response
HTTP 200
{
"data": {
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"processing_status": "failed",
"processing_error": "User-forced failure: The recording client was disconnected too long; giving up waiting (previous status: recording)"
}
}
Error Responses
| Error Code | HTTP | Description | Recommended Action |
|---|---|---|---|
recording_not_found | 404 | Recording not found or not owned by you | Verify that taskId is correct |
invalid_processing_status | 422 | The task is already in a terminal state | If completed, use DELETE; if failed, there is no need to force it again |
validation_failed | 422 | reason exceeds 500 characters or taskId is malformed | Check the length of reason and the UUID format |
POST /api/v1/tasks/{taskId}/retry (Reprocess Failed Task)
Description
Re-enqueue a task that is in the failed state for processing (ProcessRecordingJob). After a successful operation, processing_status becomes processing, and processing_error is cleared. afterCommit() is used to ensure the queue worker does not read stale values before the DB transaction commits.
Preconditions: processing_status = failed and audio_status = success and transcript_status = success. If any one fails, a 422 is returned (the details include audio_status / transcript_status to help diagnose).
For the full specification, see: Tasks API — POST retry.
Authentication
Header: X-API-Key.
Request Parameters
| Parameter | Location | Type | Required | Description |
|---|---|---|---|---|
taskId | path | string | Yes | Task ID (UUID) |
Request Example
curl -X POST "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/retry" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
Success Response
HTTP 200
{
"data": {
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"processing_status": "processing"
}
}
Error Responses
| Error Code | HTTP | Description | details Field | Recommended Action |
|---|---|---|---|---|
recording_not_found | 404 | Recording not found or not owned by you | — | Verify that taskId is correct |
invalid_processing_status | 422 | The task is not in the failed state | current_status | Only failed tasks can be retried |
invalid_processing_status | 422 | The audio / transcript was not fully uploaded | current_status, audio_status, transcript_status | Confirm the source is complete; if corrupted, use force-fail instead |
Audio Import API
The audio import API lets you upload audio files for speech recognition and translation.
POST /api/v1/imports/check-quota (Check Budget)
Description
Check whether the user's monthly budget is sufficient to upload an audio file of the specified duration. We recommend calling this API for a pre-check before uploading.
Use Cases
- Check whether the budget is sufficient before uploading an audio file
- Display the remaining available budget
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
duration_ms | integer | Yes | Audio duration (milliseconds, 1 second to 10 hours) |
Request Example
curl -X POST "https://vas-poc.vurbo.ai/api/v1/imports/check-quota" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{"duration_ms": 3600000}'
Success Response
{
"data": {
"allowed": true,
"remaining_budget": 48.48,
"is_unlimited": false,
"duration_minutes": 25,
"estimated_cost": 0.4236,
"remaining_minutes": 2864
}
}
| Field | Type | Description |
|---|---|---|
allowed | boolean | Whether the upload is allowed (true when the budget is not exceeded) |
remaining_budget | float | null | Remaining monthly budget (USD); null when there is no budget limit |
is_unlimited | boolean | Whether there is no budget limit |
duration_minutes | integer | Estimated audio duration (minutes, rounded up) |
estimated_cost | float | Estimated STT processing cost (USD) |
remaining_minutes | integer | null | Equivalent STT minutes available from the remaining budget; null when there is no budget limit |
POST /api/v1/imports (Upload Audio)
Description
Upload an audio file for speech recognition and translation. After a successful upload, processing happens in the background, and you can track progress via the status query API.
Use Cases
- Upload a recording file for transcription
- Batch process audio files
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters (multipart/form-data)
| Parameter | Type | Required | Description |
|---|---|---|---|
file | file | Yes | Audio file (mp3/wav/m4a, max 500MB) |
transcription_languages | string | Yes | Transcription languages (JSON array, e.g. ["zh-TW"]) |
translation_languages | string | No | Translation languages (JSON array, e.g. ["en-US"]) |
recognition_mode | string | Yes | Recognition mode: single / multi_speaker |
summary_template | string | No | Summary template identifier (max 50 characters) |
terminology | string | No | Terminology list (JSON object, format below) |
fuzzy_correction | string | No | Fuzzy correction rules (JSON object) |
translation_dict | string | No | Translation dictionary (JSON array) |
callback_url | string | No | Webhook callback URL (max 2048 characters) |
Webhook notification: After you set
callback_url, an HTTP POST notification is sent automatically when audio processing completes or fails. You can also specify awebhook_urlin the API Key settings as a default callback. See the Webhook Guide.
Text Processing Parameter Formats
Terminology list (terminology): improves recognition accuracy for specific terms
{
"zh-TW": [
{ "term": "語者分離", "boost": 1.5 },
{ "term": "即時轉錄", "boost": 1.5 }
]
}
- Use the language code as the key and a term array as the value
term: term text (required, max 100 characters)boost: weight (optional, default 1.0)- Up to 500 terms per language
Fuzzy correction (fuzzy_correction): automatically corrects common recognition errors
{
"zh-TW": [
{ "correct": "語者分離", "incorrect": ["語這分離", "語者分力"] }
]
}
- Use the language code as the key and a correction rule array as the value
correct: the correct term (required)incorrect: a list of incorrect variants (required)
Translation dictionary (translation_dict): specifies how proper nouns are translated
[
{ "source": "語者分離", "translations": { "en-US": "Speaker Diarization" } }
]
source: the original term (required)translations: the translation for each language (keyed by language code)- Up to 50 entries
Budget check: The monthly budget is checked automatically during upload. If the budget is exceeded, an
auth_budget_exceedederror (HTTP 402) is returned.Recommendation: Before uploading, use the
check-quotaAPI to pre-check whether the budget is sufficient, to avoid discovering an insufficient budget only after uploading a large file.
Request Example
Basic request
curl -X POST "https://vas-poc.vurbo.ai/api/v1/imports" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-F "file=@meeting.mp3" \
-F 'transcription_languages=["zh-TW"]' \
-F 'translation_languages=["en-US"]' \
-F "recognition_mode=multi_speaker"
Request with text processing settings
curl -X POST "https://vas-poc.vurbo.ai/api/v1/imports" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-F "file=@meeting.mp3" \
-F 'transcription_languages=["zh-TW"]' \
-F 'translation_languages=["en-US"]' \
-F "recognition_mode=multi_speaker" \
-F 'terminology={"zh-TW": [{"term": "語者分離", "boost": 1.5}]}' \
-F 'fuzzy_correction={"zh-TW": [{"correct": "語者分離", "incorrect": ["語這分離"]}]}' \
-F 'translation_dict=[{"source": "語者分離", "translations": {"en-US": "Speaker Diarization"}}]'
Success Response (HTTP 202)
{
"data": {
"import_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending",
"stage": null,
"progress": 0,
"message": null,
"original_filename": "meeting.mp3",
"file_size": "15.2 MB",
"task_id": null,
"error_code": null,
"error_message": null,
"created_at": "2026-01-03T10:00:00.000Z",
"updated_at": "2026-01-03T10:00:00.000Z"
}
}
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
import_file_too_large | 413 | File size exceeds the limit | Compress or split the file |
import_invalid_format | 415 | Unsupported audio format | Use mp3/wav/m4a format |
auth_budget_exceeded | 402 | Monthly budget exceeded | Wait for next month's budget reset or adjust the budget |
GET /api/v1/imports/{importId} (Query Import Status)
Description
Query the processing status and progress of the specified import task.
Use Cases
- Track the processing progress of an uploaded audio file
- Retrieve the task ID once processing completes
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
importId | string | Yes | Import ID (UUID) |
Request Example
curl -X GET "https://vas-poc.vurbo.ai/api/v1/imports/550e8400-e29b-41d4-a716-446655440000" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
Success Response
{
"data": {
"import_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"stage": "transcribing",
"progress": 45,
"message": "Recognizing speech...",
"original_filename": "meeting.mp3",
"file_size": "15.2 MB",
"task_id": null,
"error_code": null,
"error_message": null,
"created_at": "2026-01-03T10:00:00.000Z",
"updated_at": "2026-01-03T10:05:00.000Z"
}
}
| Field | Type | Description |
|---|---|---|
status | string | Status: pending / processing / completed / failed |
stage | string | Processing stage: converting / transcribing / translating / summarizing |
progress | integer | Progress percentage (0-100) |
task_id | string | The task ID after processing completes (usable with the Task API) |
error_code | string | The error code on failure |
error_message | string | The error message on failure |
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
import_not_found | 404 | Import task not found | Verify that importId is correct |
GET /api/v1/imports (List Imports)
Description
Retrieve the user's import task list (paginated).
Use Cases
- Display the import history
- View the status of all import tasks
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
per_page | integer | No | Items per page (default 20) |
Request Example
curl -X GET "https://vas-poc.vurbo.ai/api/v1/imports?per_page=20" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
Success Response
{
"data": [
{
"import_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"original_filename": "meeting.mp3",
"file_size": "15.2 MB",
"task_id": "660e8400-e29b-41d4-a716-446655440001",
"created_at": "2026-01-03T10:00:00.000Z"
}
],
"meta": {
"current_page": 1,
"last_page": 5,
"per_page": 20,
"total": 100
}
}
Audio API
Audio file streaming playback, with support for HTTP Range Requests.
GET /api/v1/sse/audio/{taskId} (Audio Streaming Playback)
Description
Stream the recording file of the specified task, with support for HTTP Range Requests to enable seek playback.
Note: Although the path contains
/sse/, this endpoint returns an audio file (not an SSE stream).
Use Cases
- Play recording audio
- Support seeking the playback position
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
taskId | string | Yes | Recording ID (i.e. recordings.id, UUID) |
Request Example
curl -X GET "https://vas-poc.vurbo.ai/api/v1/sse/audio/550e8400-e29b-41d4-a716-446655440000" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
Response Format
Full file (HTTP 200):
HTTP/1.1 200 OK
Content-Type: audio/mp4
Content-Length: 1234567
Accept-Ranges: bytes
Cache-Control: no-cache
Note: All recording audio files are returned as an M4A container (AAC encoding). Content-Type is fixed to
audio/mp4.
Partial file (HTTP 206 - Range Request):
HTTP/1.1 206 Partial Content
Content-Type: audio/mp4
Content-Length: 1024
Content-Range: bytes 0-1023/1234567
Accept-Ranges: bytes
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
recording_not_found | 404 | Recording not found | Verify that taskId is correct |
recording_audio_not_ready | 422 | The audio file has not finished uploading | Retry later |
storage_download_failed | 500 | Storage service download failed | Retry later |
Frontend Example
async function playAudio(taskId, apiKey) {
const response = await fetch(
`https://vas-poc.vurbo.ai/api/v1/sse/audio/${taskId}`,
{
headers: {
'X-API-Key': apiKey
}
}
);
const blob = await response.blob();
const audioUrl = URL.createObjectURL(blob);
const audio = new Audio(audioUrl);
audio.play();
}
TTS API
The TTS (Text-to-Speech) API provides lookup functions related to speech synthesis.
GET /api/v1/tts/voices (List TTS Voices)
Description
Retrieve the list of available TTS voices for the specified language. Each language has multiple voices to choose from, including different genders and styles.
Use Cases
- Let users choose their preferred TTS voice
- Display the available voice options
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
language | string | Yes | Language code (e.g. en-US) |
Request Example
curl -X GET "https://vas-poc.vurbo.ai/api/v1/tts/voices?language=en-US" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
Success Response
{
"data": {
"language": "en-US",
"voices": [
{
"voice_name": "en-US-JennyNeural",
"display_name": "Jenny",
"gender": "Female",
"is_default": true,
"sample_url": "https://vas-poc.vurbo.ai/api/v1/tts/voices/en-US-JennyNeural/sample"
},
{
"voice_name": "en-US-GuyNeural",
"display_name": "Guy",
"gender": "Male",
"is_default": false,
"sample_url": "https://vas-poc.vurbo.ai/api/v1/tts/voices/en-US-GuyNeural/sample"
},
{
"voice_name": "en-US-AriaNeural",
"display_name": "Aria",
"gender": "Female",
"is_default": false,
"sample_url": "https://vas-poc.vurbo.ai/api/v1/tts/voices/en-US-AriaNeural/sample"
},
{
"voice_name": "en-US-DavisNeural",
"display_name": "Davis",
"gender": "Male",
"is_default": false,
"sample_url": "https://vas-poc.vurbo.ai/api/v1/tts/voices/en-US-DavisNeural/sample"
}
]
}
}
| Field | Type | Description |
|---|---|---|
voice_name | string | Voice identifier (used by the API) |
display_name | string | Voice display name |
gender | string | Gender: Female / Male |
is_default | boolean | Whether this is the default voice for the language |
sample_url | string | Voice sample audio URL (playable directly for preview) |
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
tts_unsupported_language | 400 | Unsupported language | Use a valid language code |
GET /api/v1/tts/voices/{voiceName}/sample (Get Voice Sample Audio)
Description
Retrieve the sample audio file (MP3 format) for the specified voice. The first request synthesizes it in real time and caches it; subsequent requests are served directly from the cache.
This endpoint does not count toward TTS charges.
Use Cases
- Let users preview a voice before choosing it
- Provide voice browsing and comparison
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
voiceName | string | Yes | Voice name (e.g. en-US-JennyNeural) |
Request Example
curl -X GET "https://vas-poc.vurbo.ai/api/v1/tts/voices/zh-TW-HsiaoChenNeural/sample" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
--output sample.mp3
Success Response
The response is binary MP3 audio data (not JSON).
| Header | Value |
|---|---|
Content-Type | audio/mpeg |
Content-Length | Audio file size (bytes) |
Cache-Control | public, max-age=86400 |
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
tts_voice_not_found | 404 | Voice does not exist | Verify that the voice name is correct |
tts_sample_generation_failed | 500 | Voice sample generation failed | Retry later |
| - | 429 | Request rate too high | Wait and retry (limit 30 per minute) |
Rate Limiting
30 requests per minute per user. When the limit is exceeded, HTTP 429 is returned.
Broadcasts API
The broadcast API manages real-time subtitle streaming, including creating, querying, updating, and revoking broadcasts.
GET /api/v1/broadcasts (List Broadcasts)
Description
Query the broadcast list owned by the current API Key holder (excluding revoked channels), with pagination support.
Use Cases
- View all created broadcasts
- Manage multiple broadcast channels
- Monitor broadcast status
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
per_page | integer | No | Items per page (default 20) |
page | integer | No | Page number (default 1) |
Request Example
curl -X GET "https://vas-poc.vurbo.ai/api/v1/broadcasts?per_page=10&page=1" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
Success Response (HTTP 200)
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"token": "a3f9",
"name": "My Broadcast Channel",
"share_url": "https://vas-poc.vurbo.ai/broadcast/a3f9",
"transcription_language": "zh-TW",
"translation_languages": ["en-US", "ja-JP"],
"tts_config": null,
"speaker_diarization": false,
"summary_template": null,
"summary_language": null,
"max_viewers": 100,
"access_type": "public",
"pass_code": null,
"status": "pending",
"is_live": false,
"session_id": null,
"current_recording_id": null,
"recordings_count": 0,
"peak_viewers": 0,
"total_viewers": 0,
"duration_ms": 0,
"duration_formatted": "00:00",
"started_at": null,
"ended_at": null,
"revoked_at": null,
"created_at": "2026-01-03T10:00:00.000Z"
}
],
"meta": {
"current_page": 1,
"last_page": 5,
"per_page": 10,
"total": 50
}
}
For an explanation of the response fields, see the response fields of Create Broadcast.
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
auth_missing_api_key | 401 | API Key not provided | Make sure the header includes the API Key |
auth_invalid_api_key | 401 | Invalid API Key | Verify that the API Key is correct |
POST /api/v1/broadcasts (Create Broadcast)
Description
Create a new broadcast session for real-time subtitle streaming. After creation, a share link is generated, and viewers can receive real-time subtitles and translations through this link.
Use Cases
- Create real-time subtitles for a lecture/talk
- Create a real-time translation stream for a meeting
- Create real-time subtitles for a livestream
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
transcription_language | string | Yes | Transcription language code (e.g. zh-TW) |
translation_languages | string | No | Array of translation language codes |
name | string | No | Channel name (max 100 characters) |
access_type | string | No | Access type: public (default) or password |
pass_code | string | Conditional | Password (required when access_type is password, 4-12 characters) |
max_viewers | integer | No | Maximum number of viewers (1 to the user's plan limit, defaults to the plan limit) |
speaker_diarization | boolean | No | Speaker diarization (true or false, default false) |
tts_config | object | No | TTS default settings (key is the language code) |
tts_config.*.voice | string | No | TTS voice name (uses the default voice if not specified) |
tts_config.*.speaking_rate | number | No | TTS speaking rate (0.5-2.0, default 1.0) |
summary_template | string | No | Summary template slug (max 50 characters, must be an enabled summary category template) |
summary_language | string | No | Summary output language (defaults to transcription_language if not specified) |
callback_url | string | No | Webhook callback URL (max 2048 characters) |
Webhook notification: After you set
callback_url, an HTTP POST notification is sent automatically when broadcast recording processing completes or fails. You can also specify awebhook_urlin the API Key settings as a default callback. See the Webhook Guide.
Request Example
curl -X POST "https://vas-poc.vurbo.ai/api/v1/broadcasts" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{
"transcription_language": "zh-TW",
"translation_languages": ["en-US", "ja-JP"],
"name": "My Broadcast Channel",
"access_type": "public",
"max_viewers": 50,
"tts_config": {
"en-US": {"voice": "en-US-JennyNeural", "speaking_rate": 1.0},
"ja-JP": {"voice": "ja-JP-NanamiNeural", "speaking_rate": 1.0}
},
"summary_template": "lecture",
"summary_language": "zh-TW",
"callback_url": "https://your-server.com/webhooks/vas"
}'
Success Response (HTTP 201)
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"token": "a3f9",
"name": "My Broadcast Channel",
"share_url": "https://vas-poc.vurbo.ai/broadcast/a3f9",
"transcription_language": "zh-TW",
"translation_languages": ["en-US", "ja-JP"],
"tts_config": {
"en-US": {"voice": "en-US-JennyNeural", "speaking_rate": 1.0},
"ja-JP": {"voice": "ja-JP-NanamiNeural", "speaking_rate": 1.0}
},
"speaker_diarization": false,
"summary_template": "lecture",
"summary_language": "zh-TW",
"max_viewers": 100,
"access_type": "public",
"pass_code": null,
"status": "pending",
"is_live": false,
"session_id": null,
"current_recording_id": null,
"recordings_count": 0,
"peak_viewers": 0,
"total_viewers": 0,
"duration_ms": 0,
"duration_formatted": "0:00",
"started_at": null,
"ended_at": null,
"revoked_at": null,
"created_at": "2026-01-03T10:00:00.000Z"
}
}
| Field | Type | Description |
|---|---|---|
id | string | Broadcast ID (UUID) |
token | string | Share token (4-character short code, character set a-z0-9) |
name | string | Broadcast name |
share_url | string | Share link |
transcription_language | string | Transcription language |
translation_languages | array | Translation language list |
tts_config | object | TTS default settings (key is the language code) |
speaker_diarization | boolean | Speaker diarization toggle |
summary_template | string | Summary template slug (null means not set) |
summary_language | string | Summary output language (null defaults to transcription_language) |
max_viewers | integer | Maximum number of viewers |
access_type | string | Access type: public or password |
pass_code | string | Plaintext password (set when access_type is password, otherwise null) |
status | string | Status (see below) |
is_live | boolean | Whether currently live (true when in the active or paused state) |
session_id | string | WebSocket Session ID |
current_recording_id | string | Current recording UUID (set only when live) |
recordings_count | integer | Number of historical recordings |
peak_viewers | integer | Historical peak viewer count |
total_viewers | integer | Cumulative viewer count |
duration_ms | integer | Broadcast duration (milliseconds) |
duration_formatted | string | Formatted duration (min:sec) |
started_at | string | Start time (ISO 8601) |
ended_at | string | End time (ISO 8601) |
revoked_at | string | Revocation time (ISO 8601) |
created_at | string | Creation time (ISO 8601) |
Broadcast Status
| Status | Description |
|---|---|
pending | Waiting to start (created, not yet started) |
active | Broadcasting |
paused | Paused |
ended | Ended |
revoked | Revoked |
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
auth_missing_api_key | 401 | API Key not provided | Make sure the header includes the API Key |
auth_invalid_api_key | 401 | Invalid API Key | Verify that the API Key is correct |
validation_failed | 422 | Parameter validation failed | Verify that the parameter format is correct |
GET /api/v1/broadcasts/{id} (Query Broadcast Status)
Description
Query detailed information and the current status of the specified broadcast.
Use Cases
- Check whether the broadcast has started
- Monitor the viewer count
- Confirm the broadcast status
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Broadcast ID (UUID) |
Request Example
curl -X GET "https://vas-poc.vurbo.ai/api/v1/broadcasts/550e8400-e29b-41d4-a716-446655440000" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
Success Response (HTTP 200)
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"token": "a3f9",
"name": "My Broadcast Channel",
"share_url": "https://vas-poc.vurbo.ai/broadcast/a3f9",
"transcription_language": "zh-TW",
"translation_languages": ["en-US", "ja-JP"],
"tts_config": {
"en-US": {"voice": "en-US-AvaMultilingualNeural"},
"ja-JP": {"voice": "ja-JP-NanamiNeural"}
},
"speaker_diarization": true,
"summary_template": "lecture",
"summary_language": "zh-TW",
"max_viewers": 100,
"access_type": "public",
"status": "active",
"is_live": true,
"session_id": "ws_session_xyz",
"current_recording_id": "660e8400-e29b-41d4-a716-446655440001",
"recordings_count": 1,
"peak_viewers": 25,
"total_viewers": 30,
"duration_ms": 1800000,
"duration_formatted": "30:00",
"started_at": "2026-01-03T10:00:00.000Z",
"ended_at": null,
"revoked_at": null,
"created_at": "2026-01-03T09:55:00.000Z"
}
}
For an explanation of the response fields, see the response fields of Create Broadcast.
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
broadcast_session_not_found | 404 | The specified broadcast was not found | Verify that the broadcast ID is correct |
PATCH /api/v1/broadcasts/{id} (Update Broadcast Settings)
Description
Dynamically update broadcast settings, including access type, maximum viewer count, transcription language, and translation languages. This API can be called while a broadcast is in progress (active or paused state) to adjust settings in real time.
Use Cases
- Change a public broadcast to password protected
- Change a password-protected broadcast to public
- Adjust the maximum viewer count
- Change the transcription language (e.g. from Chinese to English)
- Add or remove translation languages
- Turn speaker diarization on or off
- Dynamically adjust settings while live
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Broadcast ID (path parameter) |
access_type | string | No | Access type: public or password |
pass_code | string | Conditional | Password (4-12 characters, required when access_type is password) |
max_viewers | integer | No | Maximum number of viewers (1 to the system limit) |
transcription_language | string | No | Transcription language (e.g. zh-TW, en-US, ja-JP) |
translation_languages | array | No | Translation language list (e.g. ["en-US", "ja-JP"]) |
speaker_diarization | boolean | No | Speaker diarization toggle (true or false) |
tts_config | object | No | TTS default settings (overrides existing settings; null means clear) |
summary_template | string | No | Summary template slug (max 50 characters, an empty string "" means clear) |
summary_language | string | No | Summary output language (an empty string "" means clear) |
Note: At least one field must be provided. Passing
nullfortts_configclears the settings; omitting it means no change.
Request Example
# Change to password protected
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/broadcasts/550e8400-e29b-41d4-a716-446655440000" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{
"access_type": "password",
"pass_code": "mySecret123"
}'
# Adjust the maximum viewer count
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/broadcasts/550e8400-e29b-41d4-a716-446655440000" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{
"max_viewers": 200
}'
# Change the transcription and translation languages
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/broadcasts/550e8400-e29b-41d4-a716-446655440000" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{
"transcription_language": "en-US",
"translation_languages": ["zh-TW", "ja-JP", "ko-KR"]
}'
# Turn on speaker diarization
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/broadcasts/550e8400-e29b-41d4-a716-446655440000" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{
"speaker_diarization": true
}'
# Update the TTS default settings
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/broadcasts/550e8400-e29b-41d4-a716-446655440000" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{
"tts_config": {
"zh-TW": {"voice": "zh-TW-HsiaoChenNeural", "speaking_rate": 1.0},
"ja-JP": {"voice": "ja-JP-NanamiNeural", "speaking_rate": 1.2}
}
}'
Success Response (HTTP 200)
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"token": "a3f9",
"name": "My Broadcast Channel",
"share_url": "https://vas-poc.vurbo.ai/broadcast/a3f9",
"transcription_language": "zh-TW",
"translation_languages": ["en-US", "ja-JP"],
"tts_config": {
"en-US": {"voice": "en-US-JennyNeural", "speaking_rate": 1.0},
"ja-JP": {"voice": "ja-JP-NanamiNeural", "speaking_rate": 1.0}
},
"speaker_diarization": true,
"summary_template": "lecture",
"summary_language": "zh-TW",
"access_type": "password",
"pass_code": "mySecret123",
"max_viewers": 200,
"status": "active",
"is_live": true,
"session_id": "ws_session_xyz",
"current_recording_id": "660e8400-e29b-41d4-a716-446655440001",
"recordings_count": 1,
"peak_viewers": 25,
"total_viewers": 30,
"duration_ms": 1800000,
"duration_formatted": "30:00",
"started_at": "2026-01-03T10:00:00.000Z",
"ended_at": null,
"revoked_at": null,
"created_at": "2026-01-03T09:55:00.000Z"
}
}
For an explanation of the response fields, see the response fields of Create Broadcast.
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
broadcast_session_not_found | 404 | The specified broadcast was not found | Verify that the broadcast ID is correct |
broadcast_cannot_update | 422 | Only pending/active/paused broadcasts can be updated | Check the current broadcast status |
validation_failed | 422 | Parameter validation failed | Verify that the parameter format is correct |
DELETE /api/v1/broadcasts/{id} (Revoke Broadcast)
Description
Revoke a broadcast that has not yet started. Only broadcasts in the pending state can be revoked.
Use Cases
- Cancel a broadcast that has not yet started
- Clean up broadcasts you no longer need
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Broadcast ID (UUID) |
Request Example
curl -X DELETE "https://vas-poc.vurbo.ai/api/v1/broadcasts/550e8400-e29b-41d4-a716-446655440000" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
Success Response (HTTP 200)
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"token": "a3f9",
"name": "My Broadcast Channel",
"share_url": "https://vas-poc.vurbo.ai/broadcast/a3f9",
"transcription_language": "zh-TW",
"translation_languages": ["en-US", "ja-JP"],
"tts_config": null,
"speaker_diarization": false,
"summary_template": null,
"summary_language": null,
"max_viewers": 100,
"access_type": "public",
"status": "revoked",
"is_live": false,
"session_id": null,
"current_recording_id": null,
"recordings_count": 0,
"peak_viewers": 0,
"total_viewers": 0,
"duration_ms": 0,
"duration_formatted": "0:00",
"started_at": null,
"ended_at": null,
"revoked_at": "2026-01-03T10:05:00.000Z",
"created_at": "2026-01-03T10:00:00.000Z"
}
}
For an explanation of the response fields, see the response fields of Create Broadcast.
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
broadcast_session_not_found | 404 | The specified broadcast was not found | Verify that the broadcast ID is correct |
broadcast_cannot_revoke | 422 | Only broadcasts in the pending state can be revoked | Check the current broadcast status |
DELETE /api/v1/broadcasts/batch (Batch Revoke Broadcasts)
Description
Batch revoke multiple broadcasts. Only broadcasts in the pending state are revoked; IDs in other states are ignored. Up to 100 can be operated on per request.
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Location | Type | Required | Description |
|---|---|---|---|---|
ids | body | array | Yes | Array of broadcast IDs (each element a UUID, up to 100) |
Request Example
curl -X DELETE "https://vas-poc.vurbo.ai/api/v1/broadcasts/batch" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{
"ids": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
]
}'
Success Response (HTTP 200)
{
"data": {
"affected_count": 2
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
data.affected_count | number | Number of broadcasts actually revoked (only pending-state broadcasts are counted) |
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
validation_failed | 422 | Parameter validation failed | Make sure ids is an array of UUIDs with no more than 100 entries |
Viewer API
The viewer-side API does not require API Key authentication. It is used for viewers to view broadcast information and verify passwords.
GET /api/v1/viewer/broadcasts/{token} (Get Broadcast Public Info)
Description
Retrieve the public information of the specified broadcast, for the viewer side to display channel information.
Use Cases
- Display channel information before a viewer enters the broadcast page
- Determine whether a password is required
Authentication
No authentication required
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
token | string | Yes | Broadcast token (4-character short code a-z0-9) |
Request Example
curl -X GET "https://vas-poc.vurbo.ai/api/v1/viewer/broadcasts/a3f9"
Success Response (HTTP 200)
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "My Broadcast Channel",
"access_type": "password",
"requires_password": true,
"status": "active",
"is_live": true,
"transcription_language": "zh-TW",
"translation_languages": ["en-US", "ja-JP"],
"tts_languages": ["en-US", "ja-JP"],
"tts_voices": {
"en-US": [
{ "voice_name": "en-US-JennyNeural", "display_name": "Jenny", "gender": "Female" },
{ "voice_name": "en-US-GuyNeural", "display_name": "Guy", "gender": "Male" }
],
"ja-JP": [
{ "voice_name": "ja-JP-NanamiNeural", "display_name": "Nanami", "gender": "Female" },
{ "voice_name": "ja-JP-KeitaNeural", "display_name": "Keita", "gender": "Male" }
]
}
}
}
| Field | Type | Description |
|---|---|---|
id | string | Broadcast ID (UUID) |
name | string | Channel name |
access_type | string | Access type: public/password |
requires_password | boolean | Whether password verification is required |
status | string | Broadcast status |
is_live | boolean | Whether currently live |
transcription_language | string | Transcription language |
translation_languages | array | Translation language list |
tts_languages | array | Languages that support TTS (obtained dynamically while live, otherwise default values) |
tts_voices | object | TTS voice list for each translation language |
tts_voices structure:
tts_voices is an object keyed by language code, where each language contains an array of available voices:
| Field | Type | Description |
|---|---|---|
voice_name | string | Voice name (for API use) |
display_name | string | Display name |
gender | string | Gender: Female/Male |
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
broadcast_token_invalid | 404 | Invalid token | Verify that the token is correct |
broadcast_token_revoked | 410 | Token revoked | The broadcast has been revoked |
POST /api/v1/viewer/broadcasts/{token}/verify (Password Verification)
Description
Verify the password and obtain a viewer access token. The obtained viewer_access_token is used to connect to the SSE real-time subtitle stream.
Use Cases
- Verify the password before a viewer enters a password-protected broadcast
- Obtain the viewer_access_token required for the SSE connection
Authentication
No authentication required
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
token | string | Yes | Broadcast token (path parameter) |
password | string | Yes | Channel password (max 12 characters) |
Request Example
curl -X POST "https://vas-poc.vurbo.ai/api/v1/viewer/broadcasts/a3f9/verify" \
-H "Content-Type: application/json" \
-d '{
"password": "mySecret123"
}'
Success Response (HTTP 200)
Correct password:
{
"data": {
"viewer_access_token": "aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vWaB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW",
"expires_at": "2026-01-04T10:00:00.000Z"
}
}
Public channel (no password required):
{
"data": {
"viewer_access_token": null,
"message": "This channel is public; no password verification is required"
}
}
| Field | Type | Description |
|---|---|---|
viewer_access_token | string | Viewer access token (valid for 24 hours) |
expires_at | string | Token expiration time (ISO 8601) |
Usage: After obtaining the
viewer_access_token, include it when connecting to SSE:GET /broadcast/{token}/text?viewer_access_token=xxx
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
broadcast_token_invalid | 401 | Invalid token | Verify that the token is correct |
broadcast_password_incorrect | 401 | Incorrect password | Re-enter the correct password |
validation_failed | 422 | Parameter validation failed | Verify that the password format is correct |
Recording Speaker Editing API
The Recording Speaker editing API provides transcript speaker editing for offline recordings, behaving consistently with the Speaker editing feature of the real-time mode WebSocket.
Limitation: This API applies only to recordings in multi-speaker recognition mode (
multi_speaker). Single-speaker recordings return aspeaker_diarization_requirederror.
PATCH /api/v1/tasks/{taskId}/speakers/rename (Globally Rename Speaker)
Description
Globally rename the specified speaker ID to a new name. This operation updates the speakerAliases mapping and updates the speaker field of all transcript entries that use that speaker ID to the new name.
Use Cases
- Change an automatically recognized speaker ID (e.g.
Guest-1) to a real name - Uniformly change the display name of a speaker
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
taskId | string | Yes | Task UUID (path parameter, the same value as the legacy recordingId) |
speaker_id | string | Yes | The original speaker ID (e.g. Guest-1); the current display label is also accepted for consecutive renames; max 100 characters |
new_label | string | Yes | The new display label; max 100 characters, must not contain control characters (\x00-\x1F, \x7F) or line breaks (it is written to the transcript blob and export files) |
Request Example
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/speakers/rename" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{
"speaker_id": "Guest-1",
"new_label": "Manager Wang"
}'
Success Response (HTTP 200)
{
"data": {
"speaker_id": "Guest-1",
"new_label": "Manager Wang",
"affected_sids": [1, 3, 5, 8, 12]
}
}
| Field | Type | Description |
|---|---|---|
speaker_id | string | The resolved original speaker ID (even if the request sends a display label, the response is the original ID) |
new_label | string | The new display label |
affected_sids | array<int> | List of affected sentence SIDs |
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
recording_not_found | 404 | The specified recording was not found | Verify that recordingId is correct |
speaker_transcript_not_found | 404 | Transcript not found | Confirm the recording has finished transcribing |
speaker_diarization_required | 422 | This feature requires diarization recording | Applies only to recordings in multi-speaker recognition mode |
speaker_name_empty | 422 | new_label is empty | Provide a valid new_label |
validation_failed | 422 | Parameter validation failed | Check the length and characters of speaker_id / new_label (must not contain control characters) |
PATCH /api/v1/tasks/{taskId}/speakers/reassign (Reassign a Single Sentence Speaker)
Description
Change the speaker identity of a single sentence, assigning the sentence to an existing speaker.
Use Cases
- Correct speaker recognition errors
- Reassign a sentence to the correct speaker
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
taskId | string | Yes | Task UUID (path parameter, the same value as the legacy recordingId) |
sid | integer | Yes | Sentence number |
target_speaker_id | string | Yes | The target speaker's original ID (taken from init_sentence.speaker_id; display labels are not accepted); max 100 characters |
Request Example
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/speakers/reassign" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{
"sid": 5,
"target_speaker_id": "Guest-2"
}'
Success Response (HTTP 200)
{
"data": {
"sid": 5,
"old_speaker_id": "Guest-1",
"new_speaker_id": "Guest-2",
"new_speaker_label": "Lily Lee"
}
}
| Field | Type | Description |
|---|---|---|
sid | integer | The ID of the modified sentence |
old_speaker_id | string | The original speaker ID |
new_speaker_id | string | The new original speaker ID |
new_speaker_label | string | The new speaker display label (after applying speaker_aliases; equals new_speaker_id when there is no alias) |
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
recording_not_found | 404 | The specified recording was not found | Verify that recordingId is correct |
speaker_transcript_not_found | 404 | Transcript not found | Confirm the recording has finished transcribing |
speaker_diarization_required | 422 | This feature requires diarization recording | Applies only to recordings in multi-speaker recognition mode |
speaker_sid_not_found | 422 | The specified sentence was not found | Confirm that sid exists |
speaker_not_found | 422 | The specified speaker was not found | Confirm that target_speaker_id exists |
invalid_data | 422 | Creating a new speaker is not supported | Use an existing speaker ID |
validation_failed | 422 | Parameter validation failed | Verify that the parameter format is correct |
PATCH /api/v1/tasks/{taskId}/speakers/merge (Merge Speakers)
Description
Assign all sentences of the source speaker to the target speaker; the source's alias (if any) is transferred to the target. This applies when the diarization model mistakenly identifies the same person as two speakers.
vs. reassign:
reassignchanges only a single sentence;mergechanges all sentences of the speaker. vs. rename:renamechanges only the display name;mergeconsolidates multiple speakers.
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
taskId | string | Yes | Task ID (UUID, path parameter) |
source_speaker_id | string | Yes | The original speaker ID or current display label to be merged (e.g. Guest-2 or Manager Wang), max 100 characters |
target_speaker_id | string | Yes | The original ID or current display label of the merge target speaker (e.g. Guest-1), max 100 characters |
Request Example
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/speakers/merge" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{
"source_speaker_id": "Guest-2",
"target_speaker_id": "Guest-1"
}'
Success Response (HTTP 200)
{
"data": {
"source_speaker_id": "Guest-2",
"target_speaker_id": "Guest-1",
"target_speaker_label": "Manager Wang",
"affected_sids": [3, 5, 7]
}
}
| Field | Type | Description |
|---|---|---|
source_speaker_id | string | The original speaker ID to be merged (resolved back to the original ID even if the request sends a display label) |
target_speaker_id | string | The original speaker ID of the merge target |
target_speaker_label | string | The target speaker display label (after applying speaker_aliases; equals the original ID when there is no alias) |
affected_sids | array<int> | List of affected sentence SIDs |
Error Responses
| Error Code | HTTP Status | Description | Recommended Action |
|---|---|---|---|
merge_speakers_same_id | 400 | Source and target are the same speaker | Provide different speaker IDs |
speaker_name_empty | 400 | Source or target is an empty string | Provide a valid speaker ID |
speaker_not_found | 404 | Source or target does not exist in the recording | Verify that the speaker ID is correct |
recording_not_found | 404 | Recording not found | Verify that taskId is correct |
speaker_transcript_not_found | 404 | Transcript not found | Confirm the recording has finished transcribing |
speaker_diarization_required | 422 | The recording is not in multi-speaker mode | Applies only to recognition_mode: multi_speaker |
validation_failed | 422 | Parameter validation failed | Confirm both source and target are provided |
For the full specification, see reference/rest/speakers.md.
Recording Entry Editing API (added in v1.4.0)
For historical recordings, this provides an API to correct the STT original text of a single sentence. After correction, you can call GET /api/v1/sse/recordings/{taskId}/entries/{sid}/retranslate to retranslate automatically. For the full specification, see reference/rest/entries.md.
PATCH /api/v1/tasks/{taskId}/entries/{sid} (Edit a Single Sentence's Original Text)
Description
Edit the original text (original_text) of a single sentence in a historical recording. On the first edit, the system automatically backs up the raw STT output to original_text_raw, and writes original_text_edited_at and the transcript revision. This changes only the original text, not the translation — to retranslate, call the corresponding SSE endpoint.
Limitations
- Only recordings with
processing_status === completedare allowed; in-progress recordings returnrecording_not_completed - Optimistic locking: you can pass
expected_revision; a mismatch returns 409transcript_revision_conflict
Authentication
Header: X-API-Key
Request Parameters
| Parameter | Location | Type | Required | Description |
|---|---|---|---|---|
taskId | path | string | Yes | Task ID (UUID, the same value as the legacy recordingId) |
sid | path | number | Yes | Sentence ID (1-based) |
original_text | body | string | Yes | The corrected original text, 1–2000 characters |
expected_revision | body | number | No | Optimistic lock; the current transcript revision |
Request Example
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/tasks/{taskId}/entries/5" \
-H "X-API-Key: vas_xxx" \
-H "Content-Type: application/json" \
-d '{ "original_text": "The corrected text", "expected_revision": 3 }'
Success Response (HTTP 200)
{
"data": {
"sid": 5,
"original_text": "The corrected text",
"original_text_raw": "The raw STT output",
"original_text_edited_at": "2026-05-06T10:30:00.000000Z",
"translated_texts": { "en-US": "The outdated old translation" },
"revision": 4
}
}
Existing translations are not updated automatically; after receiving the response, the frontend should call
GET /api/v1/sse/recordings/{taskId}/entries/{sid}/retranslateto retranslate.
Error Responses
| Error Code | HTTP | Description |
|---|---|---|
recording_not_found | 404 | The recording does not exist or does not belong to the user |
recording_not_completed | 422 | The recording has not finished processing |
entry_not_found | 404 | The specified sentence was not found |
entry_text_empty | 422 | The original text is empty |
entry_text_too_long | 422 | The original text exceeds 2000 characters |
transcript_revision_conflict | 409 | The revision does not match; it was modified by another request |
speaker_transcript_not_found | 404 | The transcript blob was not found |
For the full specification and an "edit + automatic retranslate" workflow example, see reference/rest/entries.md.
Summary Template API
The summary template API provides a list of available summary templates, used to choose the summary style when importing audio files.
GET /api/v1/summary-templates (List Summary Templates)
For the full schema, see reference/rest/summary-templates.md.
Description
Retrieve the list of available summary templates. Each template represents a different summary style, suitable for different scenarios (such as meetings, medical consultations, legal consultations, etc.).
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Location | Type | Required | Default | Description |
|---|---|---|---|---|---|
category | query | string | No | summary | Template category filter: summary / medical / legal / all |
Request Example
curl -X GET "https://vas-poc.vurbo.ai/api/v1/summary-templates?category=medical" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
Success Response
{
"data": [
{ "slug": "general", "name": "General Summary", "description": "...", "category": "summary" },
{ "slug": "meeting", "name": "Meeting Summary", "description": "...", "category": "summary" },
{ "slug": "meeting_minutes", "name": "Meeting Minutes", "description": "...", "category": "summary" },
{ "slug": "speech", "name": "Speech Summary", "description": "...", "category": "summary" },
{ "slug": "interview", "name": "Interview Summary", "description": "...", "category": "summary" },
{ "slug": "course", "name": "Course Summary", "description": "...", "category": "summary" }
]
}
| Field | Type | Description |
|---|---|---|
slug | string | Template identifier (used in API parameters) |
name | string | Template name |
description | string | Template description (may be null) |
category | string | Template category (summary / medical / legal) |
Error Responses
| Error Code | HTTP | Description | Recommended Action |
|---|---|---|---|
auth_missing_api_key | 401 | API Key not provided | Make sure the header includes the API Key |
auth_invalid_api_key | 401 | Invalid API Key | Verify that the API Key is correct |
invalid_category | 400 | category is not in the allow list | Use summary / medical / legal / all instead |
GET /api/v1/summary-templates/{slug} (Get a Single Summary Template's Details)
Exposes the full raw text of the built-in template's prompt definition, for reference when enterprise customers integrate. For the full schema, see reference/rest/summary-templates.md.
Authentication
Header: X-API-Key: YOUR_API_KEY
Request Parameters
| Parameter | Location | Type | Required | Description |
|---|---|---|---|---|
slug | path | string | Yes | Template identifier |
Request Example
curl -X GET "https://vas-poc.vurbo.ai/api/v1/summary-templates/medical_consultation" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
Success Response
{
"data": {
"slug": "medical_consultation",
"name": "Medical Consultation",
"description": "Medical consultation record template",
"category": "medical",
"system_prompt": "You are a professional medical records specialist...",
"template_prompt": "[Task]\nGenerate a structured summary...",
"output_format": "[Summary Template Begin]\n## Patient Information\n..."
}
}
Error Responses
| Error Code | HTTP | Description |
|---|---|---|
template_not_found | 404 | The template with the specified slug does not exist or has been disabled (is_active=false) |
Generate Summary API (Bearer Authentication)
Generates a meeting summary for any transcript text (not limited to text from a VAS recording), with the response streamed segment by segment over SSE. This endpoint is independent of the recording workflow and can be used to integrate transcripts from external sources.
To regenerate a summary for "a recording already uploaded to VAS", use the SSE endpoint
GET / POST /api/v1/sse/regenerate/summary/{taskId}instead.For the full schema and SSE event sequence, see reference/rest/summary.md.
POST /api/v1/summary (Generate a Summary for Any Transcript)
Authentication
⚠️ Different from other REST endpoints: This endpoint uses Bearer-token authentication, which differs from the X-API-Key used by other REST endpoints:
Authorization: Bearer vas_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Request Parameters (JSON Body)
| Field | Type | Required | Constraint / Default | Description |
|---|---|---|---|---|
content | string | Yes | ≤100,000 characters | The transcript content to summarize |
mode | string | Yes | enum "builtin" | "custom" | Explicit path selection |
template | string | required for builtin / forbidden for custom | exists prompt_templates.slug | Built-in template slug |
prompt | string | required for custom / forbidden for builtin | ≤2000 characters | The customer's complete prompt (replaces the built-in template) |
prompt_slug | string | required for custom / forbidden for builtin | ≤64 characters, Unicode, no control characters | The customer's own identifier (pass-through) |
format | string | No | bullet_points / paragraph / structured (default bullet_points) | Built-in output format |
language | string | No | - | Output language code (e.g. zh-TW, en-US) |
plain_text | bool | No | default false | Request plain-text output (the backend post-processes Markdown to remove # / * / ** / list markers) |
max_length | int | No | - | Maximum word count of the summary |
Mutual exclusivity rule: violations → 400 summary_mode_field_mismatch.
Request Example
# builtin mode (applies a built-in template)
curl -N -X POST "https://vas-poc.vurbo.ai/api/v1/summary" \
-H "Authorization: Bearer vas_..." \
-H "Content-Type: application/json" \
-d '{
"content": "...transcript...",
"mode": "builtin",
"template": "general",
"language": "zh-TW",
"plain_text": false
}'
# custom mode (full custom prompt)
curl -N -X POST "https://vas-poc.vurbo.ai/api/v1/summary" \
-H "Authorization: Bearer vas_..." \
-H "Content-Type: application/json" \
-d '{
"content": "...transcript...",
"mode": "custom",
"prompt": "You are a meeting notes assistant. List all amounts discussed and committed dates in a bulleted list.",
"prompt_slug": "client_x_finance_v3",
"language": "zh-TW"
}'
Response (SSE Stream)
The event sequence is, in order, start → chunk ×N → done (or error). The done event includes final_content / mode / template (effective slug) / plain_text; custom mode always includes prompt_snapshot (a verbatim snapshot of the customer's prompt, the only basis for reconstruction). For the full payload, see reference/rest/summary.md.
Error Codes
| Error Code | HTTP | Description |
|---|---|---|
auth_missing_token | 401 | The Authorization header was not provided |
auth_invalid_api_key | 401 | Invalid API Key |
summary_text_empty | 400 | content is empty |
summary_text_too_long | 400 | content exceeds the 100,000-character limit |
summary_invalid_mode | 400 | mode is not builtin / custom |
summary_mode_field_mismatch | 400 | The mode and field combination do not match (required field missing / forbidden field included) |
summary_prompt_too_long | 400 | prompt exceeds 2000 characters |
summary_prompt_slug_too_long | 400 | prompt_slug exceeds 64 characters |
summary_prompt_slug_invalid | 400 | prompt_slug contains control characters (\n / \r / \t / \0, etc.) |
summary_generation_failed | 500 | LLM generation failed (the raw error is already sanitized) |
Error Handling
Unified Error Format
All API errors follow a unified format:
Simple format (external API):
{
"error_code": "auth_invalid_api_key",
"message": "Invalid API key"
}
Detailed format (internal API):
{
"type": "error",
"data": {
"error_code": "auth_invalid_api_key",
"severity": "fatal",
"message": "Invalid or expired API key",
"context": "auth",
"request_id": "req_abc123xyz789",
"timestamp": "2025-12-13T10:30:45.123Z",
"details": null
}
}
Error Code Overview
Authentication Errors
| error_code | HTTP Status | severity | Description |
|---|---|---|---|
auth_missing_api_key | 401 | fatal | API Key not provided |
auth_invalid_api_key | 401 | fatal | Invalid API Key |
auth_key_expired | 401 | fatal | API Key expired |
Resource Errors
| error_code | HTTP Status | Description |
|---|---|---|
recording_not_found | 404 | Recording does not exist |
recording_audio_not_ready | 422 | Audio file not ready |
Broadcast Errors
| error_code | HTTP Status | Description |
|---|---|---|
broadcast_not_found | 404 | Broadcast not found |
broadcast_session_ended | 410 | Broadcast ended |
broadcast_unauthorized | 403 | Unauthorized access |
Version: V1.5.7 Last Updated: 2026-05-20