← Back to blog

YouTube Captions API: Auto vs Manual Captions Explained

David Boulen · 7/23/2026 · 7 min read

YouTube Captions API: Auto vs Manual Captions Explained

YouTube Captions API: Auto vs Manual Captions Explained

When you call a YouTube captions API, the response you get depends heavily on what caption tracks the creator actually published. Understanding the difference between auto-generated and manually uploaded captions before you write your first line of code saves real debugging time later.

Two Types of Captions, Very Different Quality

YouTube generates captions two ways.

Manual captions are uploaded by the creator as an.srt,.vtt, or.sbv file. The creator either wrote them by hand, paid a transcription service, or used a third-party tool. These tracks display in YouTube's UI with just the language name: "English", "Spanish", "French". Accuracy for well-produced manual captions is typically 99% or higher.

Auto-generated captions are produced by YouTube's automatic speech recognition (ASR) system, usually within 12 to 24 hours of upload. They show in the UI as "English (auto-generated)". According to 3Play Media's accessibility research, auto-generated captions realistically average 60 to 70% word accuracy, meaning roughly one word in three may be wrong. In studio conditions the number can reach 85 to 95%, but it falls sharply with background noise, heavy accents, or technical jargon.

That gap matters a lot depending on what you are building. A content summarizer that feeds captions into an LLM can tolerate more noise than an accessibility captioning workflow that delivers subtitles to deaf or hard-of-hearing viewers.

How Caption Availability Varies

Not every video has captions at all. A few patterns you will encounter in production:

  • No captions: Short clips, music videos, and videos with poor audio quality often have no tracks, not even auto-generated ones. The API returns a 404.
  • Auto-generated only: The majority of videos with captions fall here. YouTube has rolled out ASR across 70+ languages, but coverage is uneven.
  • Manual captions in one language: Common for professional channels that publish in a single market.
  • Multiple manual tracks: Large channels and media companies often upload captions in several languages as part of a localization workflow.
  • Mixed: A video may have a manual English track plus auto-generated tracks in French, Spanish, and Portuguese, all at the same time.

Region matters less for transcript content itself than for video availability, but certain videos are blocked in specific countries at the platform level. If a video is blocked in the region where the API server resolves the request, you will get a 404 or an empty result.

Developer writing code showing a programming interface

Fetching Captions as Clean JSON

The YouTube Transcriber API exposes captions through a single GET endpoint:

GET https://getyoutubetranscriber.com/api/v2/transcript

Authenticate with a Bearer token. The key parameters are:

| Parameter | Required | Default | Purpose | |--|--|--|--| | video_url | Yes | | YouTube video ID or full URL | | lang | No | video default | BCP-47 language code, e.g. en, fr, pt-BR | | include_timestamp | No | true | Include start and duration per segment | | send_metadata | No | false | Add title, channel, and thumbnail to the response | | format | No | json | json or text |

A successful response looks like this:

{
  "video_id": "dQw4w9WgXcQ",
  "language": "en",
  "transcript": [
    { "text": "We're no strangers to love", "start": 0.0, "duration": 3.5 },
    { "text": "You know the rules and so do I", "start": 3.5, "duration": 3.2 }
  ],
  "metadata": {
    "title": "Rick Astley - Never Gonna Give You Up",
    "author_name": "Rick Astley",
    "author_url": "https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw",
    "thumbnail_url": "https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg"
  }
}

Each segment in transcript gives you the caption text, the time offset in seconds from the start of the video, and how long that segment runs. This structure is the same whether the underlying track is manual or auto-generated. The language field at the top tells you which track was returned.

Copy-Paste Code Examples

curl

curl "https://getyoutubetranscriber.com/api/v2/transcript?video_url=dQw4w9WgXcQ&lang=en&send_metadata=true" \
  -H "Authorization: Bearer YOUR_API_KEY"

Python

import requests

API_KEY = "YOUR_API_KEY"
VIDEO_ID = "dQw4w9WgXcQ"

def fetch_captions(video_id: str, lang: str = None) -> dict:
    params = {
        "video_url": video_id,
        "include_timestamp": "true",
        "send_metadata": "true",
    }
    if lang:
        params["lang"] = lang

    response = requests.get(
        "https://getyoutubetranscriber.com/api/v2/transcript",
        headers={"Authorization": f"Bearer {API_KEY}"},
        params=params,
    )

    if response.status_code == 404:
        # No captions for this language; try the default track
        if lang:
            return fetch_captions(video_id)
        return {}

    response.raise_for_status()
    return response.json()

data = fetch_captions(VIDEO_ID, lang="en")
for segment in data.get("transcript", []):
    print(f"[{segment['start']:.1f}s] {segment['text']}")

JavaScript (Node.js)

const API_KEY = "YOUR_API_KEY";
const BASE_URL = "https://getyoutubetranscriber.com/api/v2/transcript";

async function fetchCaptions(videoId, lang = null) {
  const params = new URLSearchParams({
    video_url: videoId,
    include_timestamp: "true",
    send_metadata: "true",
  });

  if (lang) params.set("lang", lang);

  const res = await fetch(`${BASE_URL}?${params}`, {
    headers: { Authorization: `Bearer ${API_KEY}` },
  });

  if (res.status === 404 && lang) {
    // Fall back to the default caption track
    return fetchCaptions(videoId);
  }

  if (!res.ok) throw new Error(`Caption fetch failed: ${res.status}`);
  return res.json();
}

const data = await fetchCaptions("dQw4w9WgXcQ", "en");
data.transcript.forEach(({ start, text }) => {
  console.log(`[${start.toFixed(1)}s] ${text}`);
});

Handling Videos with No Captions or Auto-Only Tracks

The API returns HTTP 404 when no caption track exists for the video or the requested language. Build your fallback logic before you write the happy path.

A practical strategy:

  1. Request the specific language you want (lang=fr).
  2. On 404, retry without lang to get the video's default track.
  3. On a second 404, log the video ID for manual review or skip it in your pipeline.

For the auto-generated accuracy problem, you have two options. For use cases that need clean text, like feeding an LLM or publishing subtitles, consider post-processing the transcript with a lightweight spell-check pass or running it through a language model to clean punctuation and capitalization. The From Transcript JSON to Clean Text: Parsing Tips guide walks through practical approaches for both.

For use cases that just need keyword extraction or rough summarization, raw auto-captions are usually good enough. The word error rate matters much less when you are doing semantic search than when you are producing a verbatim transcript for publication.

Choosing the Right Caption Track Programmatically

The API does not return a track_kind field indicating whether a track is manual or auto-generated. YouTube does not expose that metadata in a structured way through captions endpoints. What you can do instead:

Compare language availability. If a video has captions in the exact language you requested and returns a clean result, you have what you need. The language field in the response tells you which track was served.

Prefer specific language codes over generic ones. Requesting pt-BR will return the Brazilian Portuguese track if one exists; falling back to pt may return a European Portuguese auto-generated track. Be precise with your BCP-47 codes.

Use send_metadata=true to log the video context. The author_name and title fields help you trace issues back to specific channels when debugging accuracy problems at scale.

Treat accuracy as a function of the channel, not just the API. Large educational channels, news organizations, and professional content creators are much more likely to upload manual captions than gaming channels or personal vlogs. If you know your data source, you can make assumptions. If you are ingesting from a broad search, assume auto-generated and plan your pipeline accordingly.

For bulk ingestion across hundreds or thousands of videos, the 10 Things to Check Before Scaling YouTube Transcript Calls post covers rate limits, error budgeting, and retry strategies in detail.

A Note on Accessibility Use Cases

If you are building captioning workflows for accessibility, the distinction between manual and auto-generated tracks becomes a compliance question, not just a quality preference. The FCC requires TV captions to reach 99% accuracy. Auto-generated YouTube captions, which average 60 to 70% word accuracy, fall well short of that bar.

For workflows where captions reach end users directly, such as generating SRT files, building embedded video players with subtitles, or serving captions through your own product, treat auto-generated tracks as a starting point that requires human review before publication. Adding a review step into your pipeline does not have to be a bottleneck: batch low-confidence segments for review while passing high-confidence ones through automatically.

Getting Started

YouTube Transcriber starts at 100 free credits with no credit card required. The captions endpoint costs one credit per successful call. Sign up, grab your Bearer token, and run the curl example above against any public video to see the JSON response format firsthand. The API docs list all parameters and error codes.

If you are building something that ingests captions across many videos, start with a small batch to profile your 404 rate and auto-caption quality before scaling up.

YouTube Captions API: Auto vs Manual Captions Explained | YouTube Transcriber