Skip to content

YouTube Transcript API

Send a YouTube URL, get the transcript back in the same request: timestamped segments as JSON, or ready-to-use SRT, VTT and plain text. Manual captions when they exist, auto-generated when they don’t — with the full language list, so you always know what you got.

What the transcript API does

A YouTube transcript API turns a video URL into its captions as structured data. Tunelio’s GET /transcript endpoint resolves the video, picks the best caption track for the language you asked for (preferring human-made subtitles over auto-generated ones), and returns every segment with its start time and duration — plus the full text joined together and a catalogue of every other language the video offers. No browser automation, no cookies, no yt-dlp to keep updated; one HTTPS request with your API key.

How it works

1. Call /transcript with a URL
Any watch, shorts, embed or youtu.be link — or the bare video ID. Add lang (default en), type (any, manual or auto) and format (json, text, srt or vtt).
2. We resolve the captions server-side
Tunelio fetches the video’s caption tracks from YouTube with its own extraction fleet, so bot checks, IP reputation and format changes never reach your code.
3. Use the response directly
JSON goes straight into your app or LLM pipeline; SRT and VTT drop into a video player; text feeds search indexes and summaries. Typical latency is about a second.

Copy-paste examples

Replace tnl_… with your API key from the Dashboard. The same key works for /info and /create.

cURL
curl -X GET "https://tunelio.dev/transcript?url=dQw4w9WgXcQ&lang=en&format=json" \
  -H "Authorization: Bearer tnl_…"
Node.js
const res = await fetch(
  "https://tunelio.dev/transcript?" + new URLSearchParams({
    url: "dQw4w9WgXcQ",
    lang: "en",
    format: "json",
  }),
  { headers: { Authorization: "Bearer " + process.env.TUNELIO_KEY } }
);
const data = await res.json();
console.log(data.full_text);
console.log(data.segments); // [{ start: 1.36, duration: 1.68, text: "..." }]
Python
import os, requests

res = requests.get(
    "https://tunelio.dev/transcript",
    params={"url": "dQw4w9WgXcQ", "lang": "en", "format": "json"},
    headers={"Authorization": f"Bearer {os.environ['TUNELIO_KEY']}"}
)
data = res.json()
print("Title:", data["title"])
print("Full text:", data["full_text"])
for seg in data["segments"]:
    print(f"[{seg['start']}s -> +{seg['duration']}s] {seg['text']}")
What comes back
{
  "video_id": "dQw4w9WgXcQ",
  "title": "Rick Astley - Never Gonna Give You Up",
  "language": "en",
  "language_name": "English",
  "is_generated": false,
  "type": "manual",
  "available_languages": [
    { "code": "en", "name": "English", "is_generated": false, "type": "manual" },
    { "code": "es", "name": "Spanish", "is_generated": true,  "type": "auto" }
  ],
  "segments_count": 61,
  "segments": [
    { "start": 18.64, "duration": 3.24, "text": "We're no strangers to love" },
    { "start": 21.88, "duration": 2.60, "text": "You know the rules and so do I" }
  ],
  "full_text": "We're no strangers to love You know the rules and so do I …",
  "status": "ok"
}

The JSON response carries the video ID and title, the language actually served (language, language_name), whether it is auto-generated (is_generated, type), the list of available_languages, segments_count, the segments array and full_text. A video with no captions at all returns 404 and the request is not charged — failed requests are refunded automatically.

Output formats

json (default)
Structured segments with start, duration and text, plus full_text and the language catalogue — for apps, RAG pipelines and analysis.
text
The whole transcript as plain text (text/plain) — for summaries, search indexing and LLM prompts.
srt
SubRip subtitles (text/srt) — for video players, editors and burn-in tools.
vtt
WebVTT (text/vtt) — for HTML5 <track> and web players.

Parameters

url
YouTube watch, shorts, embed or youtu.be URL, or the 11-character video ID. Required.
lang
Language code such as en, es, de, hi, zh. Default en. With type=any, Tunelio falls back to English and then to the first available track, and tells you which one it used.
type
any (prefer manual captions, fall back to auto-generated), manual (only human-made subtitles) or auto (only auto-generated). Default any.
format
json, text, srt or vtt. Default json.

What developers build with it

LLM and RAG pipelines
Feed timestamped segments to a model, keep the start time on every chunk, and link answers back to the exact second in the video.
Subtitles and accessibility
Serve SRT or VTT to your own player, translate captions, or ship transcripts alongside embedded videos.
Search and summaries
Index the full text so users can search inside videos; generate summaries, chapters and highlights.
Bots and automations
Telegram or Discord bots that answer “what did they say at 12:30?”, Zapier-style flows, content moderation.

Pricing

A transcript request costs 6 credits, the same as /info. New accounts get 100 free credits — enough for sixteen transcripts — with no card required. Paid plans start at $9 per month for 100,000 credits.

Compared with running youtube-transcript-api or yt-dlp yourself

Open-source libraries such as youtube-transcript-api and yt-dlp fetch captions well from a laptop. On a server they inherit YouTube’s bot checks: data-center IPs get challenged or blocked, age-restricted videos need cookies, and every YouTube change means a library update and a redeploy. Those are real costs when transcripts are a feature rather than a one-off script.

Tunelio moves that work server-side. You keep one HTTPS call and a JSON contract that does not change when YouTube does. If you only need a transcript now and then from your own machine, the free libraries are the right tool; if transcripts are in your product, the API is cheaper than the maintenance.

Frequently asked questions

Does it work for videos without manual subtitles?

Yes. With type=any (the default) Tunelio returns YouTube’s auto-generated captions when no human-made track exists, and marks the response is_generated: true so you can treat it accordingly.

Which languages are supported?

Every language the video itself offers — manual tracks and auto-generated ones. Ask for a code with lang; the response lists all available_languages so you can offer a picker.

How accurate are the timestamps?

They are YouTube’s own caption timings: each segment carries its start time and duration in seconds with centisecond precision, exactly as the player shows them.

What happens if a video has no captions?

The API returns 404 with a clear message, and the credits for that request are refunded automatically. Private and unavailable videos also return 404.

Is there a rate limit?

Trial and Pro accounts have a per-minute request limit documented on the pricing page; Ultra and Mega plans have unlimited request rate. Credits, not requests, are the unit you pay for.

Read the API docs