YouTube transcript
One caption track as segments (start_s, duration_s, text) plus the joined text, and available_languages (code, name, kind manual or asr for auto-generated, translatable).
/v1/youtube/transcriptThe track list comes from InnerTube player with YouTube's iOS client (ANDROID as fallback) — the web client's tracks are token-gated — and the track itself from YouTube's timedtext JSON. lang picks the track (creator captions over auto-generated; omit for English, else YouTube's default). Entities are decoded, line breaks become spaces, empty cues are dropped. A video without captions, or without a track in lang, is a 404 (not charged); an age-gated video is a 404 that says so. Machine translation (tlang) is not offered: YouTube answered it with HTTP 429 on every measured attempt.
Request
https://api.scrapercompany.com/v1/youtube/transcriptAuthenticate with your API key in the x-api-key header (see Authentication).
Body
JSON object. Unknown fields are rejected with 422.
- video_idstringrequiredmin length 11, max length 300
The 11-character video id (
8jPQjjsBbIc) or any YouTube video URL:watch?v=,youtu.be/,/shorts/,/embed/,/live/. Ids come fromPOST /v1/youtube/search(videos[].video_id). - langstring | nullmin length 2, max length 20, pattern ^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$
Caption language code (
en,pt-BR). Creator captions win over auto-generated ones;enalso matchesen-GB. Omit for English when the video has it, else YouTube's default track. A language the video has no track in is a 404 that lists the ones it has. - hlstringdefault
enpattern ^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,4})?$Interface language YouTube localizes texts in (
hl): relative dates, view-count wording, caption track names. Counts parse to integers only for English-style numbers. - glstringdefault
USpattern ^[A-Za-z]{2}$Content country (
gl), two letters.
Example request
curl -X POST "https://api.scrapercompany.com/v1/youtube/transcript" \
-H "x-api-key: $SCRAPERCOMPANY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_id": "8jPQjjsBbIc"
}'Response
200 — One caption track as timed segments. Metered responses carry x-credits-charged and x-credits-remaining headers (see credit headers).
{
"search_parameters": {
"engine": "youtube_transcripts",
"video_id": "8jPQjjsBbIc",
"hl": "en",
"gl": "US"
},
"video": {
"video_id": "8jPQjjsBbIc",
"title": "How to stay calm when you know you'll be stressed | Daniel Levitin | TED",
"channel_id": "UCAuUUnT6oDeKwE6v1NGQxug",
"author": "TED",
"length_seconds": 740
},
"language": {
"code": "en",
"name": "English",
"kind": "manual",
"translatable": true,
"is_default": true
},
"available_languages": [
{
"code": "ar",
"name": "Arabic",
"kind": "manual",
"translatable": true,
"is_default": false
},
{
"code": "en",
"name": "English",
"kind": "manual",
"translatable": true,
"is_default": true
}
],
"segments": [
{
"start_s": 13.24,
"duration_s": 2.56,
"text": "A few years ago, I broke into my own house."
},
{
"start_s": 16.88,
"duration_s": 1.216,
"text": "I had just driven home,"
}
],
"text": "A few years ago, I broke into my own house. I had just driven home, it was around midnight in the dead of Montreal winter,",
"meta": {
"source": "youtube",
"client": "IOS",
"wire_bytes": 141794,
"elapsed_s": 0.44
}
}Errors
Errors return a JSON body with a detail field. Failed requests are not charged. See Errors for the full list and retry advice.
| Status | Meaning | Retry? |
|---|---|---|
401Unauthorized | Missing or invalid API key. {"detail":"missing or invalid API key"} | No, fix the request |
402Payment Required | Not enough credits for this request. Only returned once credit enforcement is switched on; during the beta metering runs in shadow mode and never blocks. {"detail":"insufficient credits: this request costs 5, 0 available. Credits renew 2026-11-01."} | No, fix the request |
404Not Found | The property, stay, job or record was not found. {"detail":"job not found"} | No, fix the request |
422Unprocessable Content | Request validation failed. {"detail":[{"loc":["body","name"],"msg":"Field required","type":"missing"}]} | No, fix the request |
429Too Many Requests | Too many requests: the key's requests-per-minute limit was exceeded, or (once credit enforcement is on) the plan's concurrent-request limit. No rate-limit or Retry-After headers are sent; back off and retry. {"detail":"rate limit 60/min exceeded"} | Yes, with backoff |
502Bad Gateway | The upstream source failed, blocked the request or returned an unusable answer. Safe to retry later; failed requests are not charged. {"detail":"RuntimeError"} | Yes, with backoff |
503Service Unavailable | Temporarily unavailable: a dependency of this endpoint is down, or the upstream source changed its contract. Retry later. {"detail":"database unavailable: OperationalError"} | Yes, with backoff |
Try it
The quickest way: open this endpoint in Try it. It runs on your account with the example request filled in, shows the cost before you run, and shows the answer as a readable table next to the JSON and the code. Signed out? You sign in first and come straight back.
- Export your key:
export SCRAPERCOMPANY_API_KEY=sk_...(no key yet? request access). - Copy the cURL example above and run it in a terminal.
- Or open the interactive playground on api.scrapercompany.com, paste your key and pick this endpoint.
Questions about this page?
Send the page link and your question, and the team will answer.