API Reference
A WebSocket for live YouTube transcripts and a REST endpoint for non-live transcripts. All requests are authenticated with a Bearer API key.
Overview
The v1 API exposes two transcript surfaces: a WebSocket at /api/v1/live for currently-live YouTube videos, and a REST endpoint at /api/v1/transcript for videos that are no longer live. A usage endpoint reports remaining live minutes.
All responses are JSON. WebSocket messages are JSON-encoded text frames. Timestamps use ISO 8601; segment offsets use milliseconds.
Quickstart
Connect to the live WebSocket, send a subscribe message, and read transcript events.
// Node.js example using ws
import WebSocket from "ws";
const ws = new WebSocket("wss://livescript.live/api/v1/live", {
headers: { Authorization: `Bearer ${process.env.LIVESCRIPT_API_KEY}` },
});
ws.on("open", () => {
ws.send(JSON.stringify({
type: "subscribe",
source: "youtube",
source_id: "abc123DEF45",
language: "en",
delivery: "streaming",
}));
});
ws.on("message", (data) => {
const event = JSON.parse(data.toString());
if (event.type === "transcript" && event.status === "final") {
console.log(event.text);
}
});Endpoints
| Method | Path | Description |
|---|---|---|
| WS | /api/v1/live | Subscribe to a live YouTube video and receive transcript events. |
| GET | /api/v1/transcript | Fetch transcript segments for a non-live YouTube video. |
| GET | /api/v1/usage | Return current period minute usage and remaining balance. |
| POST | /api/v1/mcp | Model Context Protocol endpoint for AI clients (see the MCP server page). |
Live WebSocket
Open a WebSocket to wss://livescript.live/api/v1/live and send a single subscribe message. The server streams transcript events until the video ends, you disconnect, or an error closes the socket. One subscribe message is allowed per socket.
Subscribe message
{
"type": "subscribe",
"source": "youtube",
"source_id": "abc123DEF45",
"language": "en",
"delivery": "streaming"
}| Field | Type | Required | Description |
|---|---|---|---|
| type | "subscribe" | yes | Message type. Must be "subscribe". |
| source | "youtube" | yes | Source platform. Only "youtube" is supported in v1. |
| source_id | string | yes | 11-character YouTube video ID. |
| language | "en" | "multi" | no | Transcript language. Defaults to "en". |
| delivery | "streaming" | "final" | no | "streaming" emits interim and final events; "final" emits stable text only. Defaults to "streaming". |
Transcript events
A transcript segment has a stable segment_id. While status is "interim", the text may be revised; each revision increments revision. The final revision has status: "final" and is stable.
Interim revision
{
"type": "transcript",
"source": "youtube",
"source_id": "abc123DEF45",
"segment_id": "seg_8KQ2m",
"revision": 2,
"text": "good bring",
"start_ms": 124000,
"end_ms": 125200,
"status": "interim"
}Final segment
{
"type": "transcript",
"source": "youtube",
"source_id": "abc123DEF45",
"segment_id": "seg_8KQ2m",
"revision": 3,
"text": "Good morning.",
"start_ms": 124000,
"end_ms": 125700,
"status": "final"
}| Field | Type | Required | Description |
|---|---|---|---|
| type | "transcript" | yes | Event type. |
| source | "youtube" | yes | Source platform. |
| source_id | string | yes | YouTube video ID. |
| segment_id | string | yes | Stable ID for the segment. Interim updates share the same segment_id. |
| revision | number | yes | Monotonic revision counter for a segment_id. Replace prior text on a higher revision. |
| text | string | yes | Transcript text for this segment. |
| start_ms | number | yes | Segment start, in milliseconds from the stream's origin. |
| end_ms | number | yes | Segment end, in milliseconds. |
| status | "interim" | "final" | yes | "interim" segments may be revised; "final" segments are stable. |
With delivery: "final", the server omits interim revisions and only emits the final segment.
GET /api/v1/transcript
Fetch the transcript of a YouTube video that is no longer live. Returns 404 if the video has no available transcript and 409 if the video is currently live (use the WebSocket instead).
GET https://livescript.live/api/v1/transcript?source=youtube&source_id=abc123DEF45
Authorization: Bearer ls_live_xxxResponse
{
"source": "youtube",
"source_id": "abc123DEF45",
"title": "Stream title",
"transcript": [
{
"segment_id": "cap_1",
"start_ms": 0,
"text": "Welcome back to the show.",
"status": "final"
},
{
"segment_id": "cap_2",
"start_ms": 4200,
"text": "Today we're covering the markets.",
"status": "final"
}
]
}| Query parameter | Required | Description |
|---|---|---|
| source | yes | Must be "youtube". |
| source_id | yes | 11-character YouTube video ID. |
GET /api/v1/usage
Returns the authenticated account's minute consumption for the current period. Usage is measured in connected live minutes. Non-live transcript fetches do not consume live minutes.
{
"plan": "pro",
"period_ends_at": "2026-06-22T00:00:00Z",
"live_minutes": {
"included_total": 1500,
"included_remaining": 420,
"topup_remaining": 900,
"total_remaining": 1320
},
"limits": {
"concurrent_live_streams": 1
}
}Errors
Errors are returned as a JSON object with a stable code and a human-readable message. On the WebSocket, an error frame is sent immediately before the socket is closed.
{
"type": "error",
"code": "SOURCE_NOT_LIVE",
"message": "The requested YouTube video is not currently live."
}| Code | Meaning |
|---|---|
| AUTHENTICATION_FAILED | The API key is missing, invalid, expired, or not allowed to use the live API. |
| SOURCE_NOT_LIVE | The requested YouTube video exists but is not currently live. |
| SOURCE_UNAVAILABLE | LiveScript could not read the live source or YouTube rejected the stream request. |
| USAGE_LIMIT_EXCEEDED | The account has no live minutes remaining for this period or top-up balance. |
| CONCURRENT_STREAM_LIMIT | The account is already using the maximum number of concurrent live streams. |