The base URL for every endpoint below is https://transcript-yt.com. Grab a key from your dashboard first.
Pass your key as a bearer token. x-api-key also works if a header library makes that easier.
Authorization: Bearer ts_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Fetch a transcript for any public YouTube video.
| Param | Type | Description |
|---|---|---|
| url | string, required | A YouTube URL (watch, youtu.be, shorts, embed) or a bare 11-char video ID. |
| language | string, optional | BCP-47 code (e.g. es, pt-BR). Defaults to the original / English track. |
| translate_to | string, optional | BCP-47 target code. Runs YouTube's built-in caption translation on top of whichever track language selects. The response's languagebecomes the target and translated is true. |
| format | string, optional | json (default), text, srt, vtt,csv, or md. |
| includeSegments | boolean, optional | Set false to drop the timestamped array and return only full text (JSON format only). |
| timestamps | boolean, optional | Set true to prefix each line with a [HH:MM:SS] marker intext and md output. Formatting is free — no extra credit cost. |
| paragraphs | boolean, optional | Set true to merge segments into paragraph-length chunks (on speech pauses or a character budget) instead of raw caption cues. |
Also available as POST /v1/transcript with a JSON body of the same shape.
curl "https://transcript-yt.com/v1/transcript?url=https://youtu.be/dQw4w9WgXcQ" \ -H "Authorization: Bearer ts_live_xxxx"
{
"videoId": "dQw4w9WgXcQ",
"title": "Rick Astley - Never Gonna Give You Up",
"author": "Rick Astley",
"channelId": "UCuAXFkgsw1L7xaCfnd5JJOw",
"durationSeconds": 213,
"language": "en",
"translated": false,
"autoGenerated": false,
"segments": [
{ "start": 0.0, "duration": 4.2, "text": "♪♪♪" },
{ "start": 4.2, "duration": 3.1, "text": "We're no strangers to love" }
],
"text": "♪♪♪ We're no strangers to love ...",
"availableLanguages": [
{ "languageCode": "en", "languageName": "English", "autoGenerated": false }
]
}List available caption tracks for a video without downloading one. This call does not cost a credit.
curl "https://transcript-yt.com/v1/languages?url=dQw4w9WgXcQ" \ -H "Authorization: Bearer ts_live_xxxx"
{
"videoId": "dQw4w9WgXcQ",
"languages": [
{ "languageCode": "en", "languageName": "English", "autoGenerated": false },
{ "languageCode": "en", "languageName": "English (auto)", "autoGenerated": true },
{ "languageCode": "es-419", "languageName": "Spanish (Latin America)", "autoGenerated": false }
]
}format=srt, format=vtt, format=csv, andformat=md return files directly with a matching Content-Type — pipe the response straight to a file. Every format is generated from the same underlying transcript at no extra credit cost, including timestamps and paragraphs.
curl "https://transcript-yt.com/v1/transcript?url=dQw4w9WgXcQ&format=srt" \ -H "Authorization: Bearer ts_live_xxxx" -o captions.srt
Current plan, credit balance (plan + top-up), and rate limit. Free — never costs a credit.
curl "https://transcript-yt.com/v1/usage" \ -H "Authorization: Bearer ts_live_xxxx"
{
"plan": "STARTER",
"credits_remaining": 3820,
"plan_credits": { "total": 4000, "used": 180, "remaining": 3820 },
"topup_credits": { "remaining": 0, "grants": [] },
"period_resets_at": "2026-10-19T00:00:00.000Z",
"rate_limit_per_minute": 60
}Every error uses the same envelope, except 402 (see below):
{ "error": { "code": "NO_CAPTIONS", "message": "This video has no captions available." } }| Code | HTTP | Meaning |
|---|---|---|
| INVALID_VIDEO | 400 | Couldn't parse a video ID from the given url |
| VIDEO_UNAVAILABLE | 404 | Video is private, deleted, or region-locked |
| NO_CAPTIONS | 404 | Video has no caption tracks at all |
| LANGUAGE_NOT_AVAILABLE | 404 | Requested language isn't offered |
| UNAUTHORIZED | 401 | Missing or invalid API key |
| RATE_LIMITED | 429 | Too many requests per minute |
| BLOCKED | 503 | Temporary upstream block — retry shortly |
Out of credits is a 402 with its own flat shape rather than the error envelope above:
{
"error": "Out of credits",
"plan": "MICRO",
"credits_remaining": 0,
"upgrade_url": "https://transcript-yt.com/dashboard/billing",
"topup_url": "https://transcript-yt.com/dashboard/billing#topup"
}Failed requests (any 4xx/5xx from us) are never billed a credit.
Every response carries usage headers so you can back off before hitting a wall. A 429 also carries Retry-After (seconds):
X-RateLimit-Limit: 60 X-RateLimit-Remaining: 57 X-RateLimit-Reset: 1737403200 Retry-After: 12 X-Credits-Charged: 1 X-Credits-Remaining: 3786
X-Credits-Charged is 1 on a billed response (including cache hits) and 0 on any failure. X-Credits-Remaining is your plan balance plus any active top-up packs. See the pricing page for per-plan limits.