Answers
Why does YouTube's captions.download return 403 for videos I don't own?
Short answer
Because captions.download requires permission to edit the video: no OAuth scope fixes a 403 on someone else's upload. For public videos you don't own, the YouTube transcript endpoint returns the captions as text with timestamps for $0.004 per video, with no OAuth and no Google Cloud project.
You build the OAuth flow, request the youtube.force-ssl scope, call captions.list and see the English track. Then captions.download on that track returns 403 forbidden. Nothing is wrong with your code. Google's reference for captions.download says the method requires the user to have permission to edit the video. A logged-in viewer is not an editor, so the answer for third-party videos is always no.
What the official API allows
| Method | Quota cost | Works on other people's videos? |
|---|---|---|
captions.list |
50 units | Yes, lists the tracks |
captions.download |
200 units | No, editors only |
Listing tells you a track exists. It never gives you the words. The costs come from Google's quota table.
Getting the words for any public video
YouTube video transcript works on public videos with captions, whoever uploaded them. Send the video ID and, if you like, a preferred language:
curl -s -G "https://api.okdata.online/v1/youtube/videos/transcript/get" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
-d id=dQw4w9WgXcQ \
-d lang=en
The item has video_id, lang, text (the whole transcript) and segments, each with start and end in seconds. There is no file format to choose; build SRT or VTT from the segments if a player needs one.
| Volume | Cost |
|---|---|
| 1 video | $0.004 |
| 50 videos | $0.20 |
| 1,000 videos | $4.00 |
No OAuth consent screen, no Google Cloud project and no quota bucket to watch. You pay per transcript returned; a video without captions comes back not_found and costs nothing.
Differences from the official file
- You get text and timings, not the original caption file with its styling.
langis a preference. Read the returnedlangto see which track you got.- The response does not say whether the track was uploaded or generated automatically.
- Only public videos. Private videos are out of reach.
When the official API is the right call
- Your own channel, or a client's channel you manage. You have edit rights, so
captions.downloadworks, gives the original format and can convert withtfmt. Quota is free. - You only need to know whether a track exists.
captions.listanswers that without downloading anything. - Videos with no captions at all. Neither route helps; run speech-to-text such as Whisper on audio you are allowed to use.
Batch patterns are on the video transcript solution page, and every error code is on errors.
Updated