API reference
Every v1 endpoint, the shared response envelope, and the canonical error codes and per-video outcomes.
Endpoint reference
A dedicated endpoint per source — fetch one video, list a channel, playlist, or search, and batch up to 50 transcripts in a single call. All requests and responses are JSON, and every authenticated endpoint expects a bearer token.
/api/v1/transcripts/videoidempotentReturns a video's transcript - text plus timestamped segments.
Body parameters
Example request
Response
{
"ok": true,
"request_id": "req_…",
"data": {
"kind": "transcript",
"video_id": "dQw4w9WgXcQ",
"title": "Example video",
"text": "We're no strangers to love …",
"segments": [
{
"start": 0,
"duration": 3.5,
"text": "We're no strangers to love"
}
]
},
"usage": {
"credits_spent": 1,
"balance": 99,
"bytes": 14233
}
}/api/v1/transcripts/channelidempotentResolve a channel into a paginated list of videos (metadata only).
Body parameters
Example request
Response
{
"ok": true,
"request_id": "req_…",
"data": {
"kind": "video_list",
"source": "channel_videos",
"videos": [
{
"videoId": "dQw4w9WgXcQ",
"title": "Example video",
"thumbnailUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/mqdefault.jpg",
"duration": 212,
"channel": "Example Channel"
}
],
"next_cursor": "eyJvIjoxMH0"
},
"usage": {
"credits_spent": 1,
"balance": 98,
"bytes": 0
}
}/api/v1/transcripts/playlistidempotentResolve a playlist into a paginated list of videos (metadata only).
Body parameters
Example request
Response
{
"ok": true,
"request_id": "req_…",
"data": {
"kind": "video_list",
"source": "playlist",
"videos": [
{
"videoId": "dQw4w9WgXcQ",
"title": "Example video",
"thumbnailUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/mqdefault.jpg",
"duration": 212,
"channel": "Example Channel"
}
],
"next_cursor": "eyJvIjoxMH0"
},
"usage": {
"credits_spent": 1,
"balance": 98,
"bytes": 0
}
}/api/v1/transcripts/searchidempotentResolve a keyword search into a paginated list of videos (metadata only).
Body parameters
Example request
Response
{
"ok": true,
"request_id": "req_…",
"data": {
"kind": "video_list",
"source": "search",
"videos": [
{
"videoId": "dQw4w9WgXcQ",
"title": "Example video",
"thumbnailUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/mqdefault.jpg",
"duration": 212,
"channel": "Example Channel"
}
],
"next_cursor": "eyJvIjoxMH0"
},
"usage": {
"credits_spent": 1,
"balance": 98,
"bytes": 0
}
}/api/v1/transcripts/batchidempotentFetch transcripts for up to 50 video IDs concurrently. Charges 1 credit per successfully fetched transcript; failed or blocked videos are free.
Body parameters
Example request
Response
{
"ok": true,
"request_id": "req_…",
"data": {
"kind": "transcript_batch",
"results": [
{
"video_id": "dQw4w9WgXcQ",
"outcome": "ok",
"title": "Example video",
"text": "Full transcript text …",
"segments": [
{
"start": 0,
"duration": 3.5,
"text": "Full transcript …"
}
],
"cached": true,
"bytes": 14233
},
{
"video_id": "9bZkp7q19f0",
"outcome": "no_transcript",
"title": null,
"text": null,
"segments": null,
"cached": false,
"bytes": 0
}
]
},
"usage": {
"credits_spent": 1,
"balance": 97
}
}/api/v1/healthno authPublic liveness probe for uptime monitoring. Returns 200 whenever the API is serving. No authentication required and no credits used.
Body parameters
Example request
Response
{
"status": "ok",
"service": "transcriptfetch-api",
"version": "1.0.0",
"time": "2026-06-16T00:00:00.000Z"
}Response format
Every successful response shares the same envelope: ok, a request_id (also returned as the X-Request-Id header), a data object whose kind tells you what it holds, and a usage block.
Single transcript
The /video endpoint returns kind: "transcript" with the full text and a timestamped segments array. Each segment's start and duration are in seconds — everything you need to render timestamps or export SRT/VTT.
{
"ok": true,
"request_id": "req_…",
"data": {
"kind": "transcript",
"video_id": "dQw4w9WgXcQ",
"title": "Example video",
"text": "We're no strangers to love …",
"segments": [
{
"start": 0,
"duration": 3.5,
"text": "We're no strangers to love"
}
]
},
"usage": {
"credits_spent": 1,
"balance": 99,
"bytes": 14233
}
}Video list (channel / playlist / search)
The /channel, /playlist, and /search endpoints return kind: "video_list" — a videos array of metadata plus a next_cursor for pagination. Fetch the transcripts separately via the batch endpoint.
{
"ok": true,
"request_id": "req_…",
"data": {
"kind": "video_list",
"source": "search",
"videos": [
{
"videoId": "dQw4w9WgXcQ",
"title": "Example video",
"thumbnailUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/mqdefault.jpg",
"duration": 212,
"channel": "Example Channel"
}
],
"next_cursor": "eyJvIjoxMH0"
},
"usage": {
"credits_spent": 1,
"balance": 98,
"bytes": 0
}
}Batch
The batch endpoint returns kind: "transcript_batch" with one entry per requested video in data.results.
{
"ok": true,
"request_id": "req_…",
"data": {
"kind": "transcript_batch",
"results": [
{
"video_id": "dQw4w9WgXcQ",
"outcome": "ok",
"title": "Example video",
"text": "Full transcript text …",
"segments": [
{
"start": 0,
"duration": 3.5,
"text": "Full transcript …"
}
],
"cached": true,
"bytes": 14233
},
{
"video_id": "9bZkp7q19f0",
"outcome": "no_transcript",
"title": null,
"text": null,
"segments": null,
"cached": false,
"bytes": 0
}
]
},
"usage": {
"credits_spent": 1,
"balance": 97
}
}Field reference
data.kind—transcript,video_list, ortranscript_batch.segments— array of{ start, duration, text }cues (seconds), ornullwhen no transcript is available.next_cursor— pass back ascursorfor the next page of a list, ornullwhen exhausted.outcome(batch results) —ok,no_transcript,blocked, orerror.usage.credits_spent— credits charged for this request (0 on failures).usage.balance— your remaining credit balance (nullfor unlimited accounts).
Error codes & outcomes
Request-level failures return a canonical error object with a machine-readable code. Per-video results inside a batch carry an outcome instead — and only successful ones are billed.
Canonical error codes
| code | HTTP | Meaning |
|---|---|---|
unauthorized | 401 | Missing or invalid API key. |
invalid_request | 400 | Body failed validation - see error.issues. |
insufficient_credits | 402 | Not enough credits for the request. |
rate_limited | 429 | Per-key rate limit exceeded. Retry after backoff. |
idempotency_conflict | 409 | Idempotency-Key reused with a different body, or a request with that key is still in flight. |
upstream_unavailable | 502 | The transcript service was unreachable. Safe to retry. |
internal_error | 500 | Unexpected server error. |
HTTP status codes
| Status | Name | Meaning |
|---|---|---|
| 400 | Bad Request | Invalid body — missing/unknown endpoint, bad value, or limit out of range. Check the issues array in the response. |
| 401 | Unauthorized | Missing, malformed, revoked, or unknown API key. |
| 402 | Payment Required | Not enough credits to complete the request. Top up or upgrade your plan. |
| 409 | Conflict | Idempotency-Key reused with a different body, or a request with that key is still in flight. |
| 429 | Too Many Requests | Per-key rate limit exceeded. Wait the number of seconds in Retry-After and retry. |
| 502 | Bad Gateway | The transcript service was unreachable. Safe to retry with backoff. |
Per-video outcomes
| outcome | Charged | Meaning |
|---|---|---|
ok | 1 credit | Transcript (or video list) returned successfully. |
no_transcript | Free | The video exists but has no available transcript/captions. |
blocked | Free | The upstream request was blocked. Retry later. |
error | Free | An unexpected error occurred fetching the source. |
outcome — only ok outcomes are billed, everything else is free.
