Subtitle Feed Token API
POST /api/v1/auth/tasks/{taskId}/subtitle-feed-token
Description
Exchange for a short-lived access Token for the floating-subtitle feed. The Floating Subtitle SSE (Floating Subtitle SSE) subscribes read-only to the transcript of an in-progress recording over an independent connection. Because the browser's native EventSource does not support custom HTTP headers, a Token mechanism is used: first exchange an API Key for a feed_token bound to the recording, then connect to the SSE with that Token.
Authentication
Header: X-API-Key (see Authentication). Only the owner of the recording can exchange for a token.
Request Parameters
| Parameter | Location | Type | Required | Description |
|---|---|---|---|---|
taskId | path | string | Yes | Recording ID (must be in progress and owned by the caller) |
Request Example
curl -X POST "https://vas-poc.vurbo.ai/api/v1/auth/tasks/3f9a.../subtitle-feed-token" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
Success Response
HTTP 200
{
"token": "aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789abcdefghijkl",
"expires_in": 900
}
Response Fields
| Field | Type | Description |
|---|---|---|
token | string | Floating-subtitle access Token (48-character random string) |
expires_in | integer | Validity period (seconds), fixed at 900 |
Token Characteristics
| Characteristic | Description |
|---|---|
| Validity | 15 minutes; each successful validation on the SSE connection extends it automatically (sliding expiry) |
| Binding | Bound to the recording |
| Usage | Passed as the feed_token query parameter to GET /tasks/{task_id}/subtitle |
Race Handling
Immediately after recording starts, the backend may not have finished creating the recording. In that case the exchange returns 425 Too Early, and the client should retry after a short delay.
Specific Error Codes
Note: These three endpoints return errors as
{"error": "<code>"}— the field name iserror, notdata.error_codeas on other endpoints.
| Error Code | HTTP Status | Description | Recommended Handling |
|---|---|---|---|
recording_not_ready | 425 | Recording not ready (being created) | Retry after a short delay |
recording_ended | 410 | Recording has ended | Do not retry |
| - | 401 | Invalid API Key | Verify the API Key |
plan_feature_not_allowed | 403 | Floating subtitles not included in your unlimited plan (v1.9.0) | Upgrade the plan; check plan contents via GET /api/v1/me/plan |
Audience Sharing
Besides the recording owner, the floating subtitle can also be shared with other on-site audience members. After the owner enables sharing, they receive a share secret to embed in a share link or QR code; an audience member exchanges that secret for a read-only audience Token and connects to the Floating Subtitle SSE.
- Audience access is read-only, requires no login and no API Key, and is not charged separately.
- The number of audience members per recording is capped (server-configured, default 10, excluding the owner). The current count and limit are available via the
viewersevent of the Floating Subtitle SSE (see Floating Subtitle SSE). Use the event'smaxfield rather than hardcoding a value. - Sharing ends automatically when the recording ends.
POST /api/v1/auth/tasks/{taskId}/subtitle-share
Enable (or reset) audience sharing and return a share secret. Only the owner of the recording may call this.
Authentication: Header X-API-Key.
| Parameter | Location | Type | Required | Description |
|---|---|---|---|---|
taskId | path | string | Yes | Recording ID (must be in progress and owned by the caller) |
Success Response (HTTP 200)
{
"share_secret": "aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789abcdefghijkl",
"expires_in": 43200
}
| Field | Type | Description |
|---|---|---|
share_secret | string | Share secret; embed it in a share link / QR code for the audience. Re-enabling resets the secret and invalidates old links |
expires_in | integer | Validity period of the share secret (seconds) |
The
share_secretis returned only once, at the moment of enabling; keep it in the share link.
| Error Code | HTTP Status | Description | Recommended Handling |
|---|---|---|---|
recording_not_ready | 425 | Recording not ready (being created) | Retry after a short delay |
recording_ended | 410 | Recording has ended | Do not retry |
plan_feature_not_allowed | 403 | Floating subtitles not included in your unlimited plan (v1.9.0) | Upgrade the plan; check plan contents via GET /api/v1/me/plan |
DELETE /api/v1/auth/tasks/{taskId}/subtitle-share
Stop sharing and invalidate the share link. After stopping, no new audience members are admitted; existing audience connections end no later than their Token expiry or when the recording ends. Only the owner of the recording may call this.
Authentication: Header X-API-Key.
Success Response (HTTP 200)
{ "revoked": true }
| Field | Type | Description |
|---|---|---|
revoked | boolean | true = sharing stopped; false = recording does not exist or caller is not the owner |
POST /api/v1/public/tasks/{taskId}/subtitle-feed-token
An audience member exchanges a share secret for a read-only audience Token, then connects to the Floating Subtitle SSE with that Token. No login and no API Key required.
| Parameter | Location | Type | Required | Description |
|---|---|---|---|---|
taskId | path | string | Yes | Recording ID |
share_secret | body | string | Yes | The share secret provided by the owner |
Request Example
curl -X POST "https://vas-poc.vurbo.ai/api/v1/public/tasks/3f9a.../subtitle-feed-token" \
-H "Content-Type: application/json" \
-d '{"share_secret":"aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789abcdefghijkl"}'
Success Response (HTTP 200)
{
"token": "aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789abcdefghijkl",
"expires_in": 900
}
The response fields are the same as the owner Token above; the returned Token likewise connects to the Floating Subtitle SSE via the feed_token query parameter. If the audience limit has been reached, the connection returns 429 (see Floating Subtitle SSE).
Rate Limits
- Up to 30 requests per minute for the same recording (all viewers combined, including requests with an invalid share link).
- When a limit is exceeded, HTTP 429 is returned with a
Retry-Afterheader (the number of seconds to wait). This error uses the standard error format (data.error_codeistoo_many_requests), unlike the{"error": ...}format of this endpoint's other errors.
| Error Code | HTTP Status | Description | Recommended Handling |
|---|---|---|---|
invalid_share | 403 | Share link invalid or expired | Request a new share link from the owner |
recording_not_ready | 425 | Recording not ready (being created) | Retry after a short delay |
recording_ended | 410 | Recording has ended | Do not retry |
too_many_requests | 429 | Too many requests (see Rate Limits above; the code is in data.error_code) | Wait for the number of seconds in Retry-After, then retry |
Version: V1.24.1 Last Updated: 2026-10-05