TranscriptFetchDashboard
API reference

API reference

Every v1 endpoint, the shared response envelope, and the canonical error codes and per-video outcomes.

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.

POST/api/v1/transcripts/videoidempotent

Returns a video's transcript - text plus timestamped segments.

Body parameters

videostringrequired
A video URL or 11-character video ID. Full YouTube URLs (watch, youtu.be, /shorts/) are normalized automatically.

Example request

curl https://transcriptfetch.com/api/v1/transcripts/video \
  -H "Authorization: Bearer $TRANSCRIPTFETCH_KEY" \
  -H "Content-Type: application/json" \
  -d '{"video":"dQw4w9WgXcQ"}'

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
  }
}
POST/api/v1/transcripts/channelidempotent

Resolve a channel into a paginated list of videos (metadata only).

Body parameters

channelstringrequired
Channel @handle, /channel/UC… URL, or UC… ID.
limitinteger (1–50)optional
Max videos to return per page. Defaults to 5.
cursorstringoptional
Opaque pagination cursor from a previous response's next_cursor. Omit for the first page.

Example request

curl https://transcriptfetch.com/api/v1/transcripts/channel \
  -H "Authorization: Bearer $TRANSCRIPTFETCH_KEY" \
  -H "Content-Type: application/json" \
  -d '{"channel":"@lexfridman","limit":10}'

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
  }
}
POST/api/v1/transcripts/playlistidempotent

Resolve a playlist into a paginated list of videos (metadata only).

Body parameters

playliststringrequired
Playlist URL or playlist ID.
limitinteger (1–50)optional
Max videos to return per page. Defaults to 5.
cursorstringoptional
Opaque pagination cursor from a previous response's next_cursor. Omit for the first page.

Example request

curl https://transcriptfetch.com/api/v1/transcripts/playlist \
  -H "Authorization: Bearer $TRANSCRIPTFETCH_KEY" \
  -H "Content-Type: application/json" \
  -d '{"playlist":"PLrAXtmRdnEQy6nuLMt9H1aZIuhcGOcZQ4","limit":10}'

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
  }
}
POST/api/v1/transcripts/searchidempotent

Resolve a keyword search into a paginated list of videos (metadata only).

Body parameters

querystringrequired
Keyword search query.
limitinteger (1–50)optional
Max videos to return per page. Defaults to 5.
cursorstringoptional
Opaque pagination cursor from a previous response's next_cursor. Omit for the first page.

Example request

curl https://transcriptfetch.com/api/v1/transcripts/search \
  -H "Authorization: Bearer $TRANSCRIPTFETCH_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query":"how transformers work","limit":10}'

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
  }
}
POST/api/v1/transcripts/batchidempotent

Fetch transcripts for up to 50 video IDs concurrently. Charges 1 credit per successfully fetched transcript; failed or blocked videos are free.

Body parameters

videoIdsstring[] (1–50)required
Video IDs or URLs. Full YouTube URLs are normalized automatically.

Example request

curl https://transcriptfetch.com/api/v1/transcripts/batch \
  -H "Authorization: Bearer $TRANSCRIPTFETCH_KEY" \
  -H "Content-Type: application/json" \
  -d '{"videoIds":["dQw4w9WgXcQ","9bZkp7q19f0"]}'

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
  }
}
GET/api/v1/healthno auth

Public liveness probe for uptime monitoring. Returns 200 whenever the API is serving. No authentication required and no credits used.

Body parameters

No request body — this endpoint takes no parameters.

Example request

curl https://transcriptfetch.com/api/v1/health

Response

{
  "status": "ok",
  "service": "transcriptfetch-api",
  "version": "1.0.0",
  "time": "2026-06-16T00:00:00.000Z"
}

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.kindtranscript, video_list, or transcript_batch.
  • segments — array of { start, duration, text } cues (seconds), or null when no transcript is available.
  • next_cursor — pass back as cursor for the next page of a list, or null when exhausted.
  • outcome (batch results) — ok, no_transcript, blocked, or error.
  • usage.credits_spent — credits charged for this request (0 on failures).
  • usage.balance — your remaining credit balance (null for unlimited accounts).

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

codeHTTPMeaning
unauthorized401Missing or invalid API key.
invalid_request400Body failed validation - see error.issues.
insufficient_credits402Not enough credits for the request.
rate_limited429Per-key rate limit exceeded. Retry after backoff.
idempotency_conflict409Idempotency-Key reused with a different body, or a request with that key is still in flight.
upstream_unavailable502The transcript service was unreachable. Safe to retry.
internal_error500Unexpected server error.

HTTP status codes

StatusNameMeaning
400Bad RequestInvalid body — missing/unknown endpoint, bad value, or limit out of range. Check the issues array in the response.
401UnauthorizedMissing, malformed, revoked, or unknown API key.
402Payment RequiredNot enough credits to complete the request. Top up or upgrade your plan.
409ConflictIdempotency-Key reused with a different body, or a request with that key is still in flight.
429Too Many RequestsPer-key rate limit exceeded. Wait the number of seconds in Retry-After and retry.
502Bad GatewayThe transcript service was unreachable. Safe to retry with backoff.

Per-video outcomes

outcomeChargedMeaning
ok1 creditTranscript (or video list) returned successfully.
no_transcriptFreeThe video exists but has no available transcript/captions.
blockedFreeThe upstream request was blocked. Retry later.
errorFreeAn unexpected error occurred fetching the source.
A 200 can still carry a non-success outcome. Inside a batch, each video reports its own outcome — only ok outcomes are billed, everything else is free.
Next →Guides