REST API

YouTube transcript API for transcripts, subtitles and captions

Send a YouTube video URL, poll the job, read back a timestamped transcript with speaker tags, SRT or WebVTT. Real speech-to-text, not scraped captions: the same engine behind the app, 90+ languages, videos up to 12 hours, and captions burned into the video when you need them in the picture. See how we measure accuracy.

Get your API tokenSee pricingAPI and MCP are included on every plan. Your 10 free minutes work through the API too.

Prefer to ask Claude or ChatGPT instead of writing code? Use the MCP server.

How to start

Three steps. The token button above takes you to sign in first if you are not logged in, then straight to your token page.

  1. 1

    Create a free account, or log in

    Every account starts with 10 free minutes, no card needed. The API and MCP are included on every plan.

  2. 2

    Generate your token

    On the API page in your account. One token per account, shown once, revoke it there anytime.

  3. 3

    Send it with your first request

    Add it as an Authorization: Bearer header, POST a YouTube URL to /v1/api/transcribe and poll the job id until it is done.

Reference

Every endpoint, with the request and response you should expect. Stuck on something? Reach us through the contact page.

Full documentation

This page is the tour. The manual is next door.

Developer docs has the quickstart in curl, Python and Node, every endpoint with its parameters and response fields, what each job state means, and the errors. This page stays a summary on purpose.

Authentication

Every endpoint requires a bearer token. Generate one on your API page and send it in the Authorization header.

Authorization: Bearer ytt_<your-token>
401 Unauthorized is returned for missing or invalid tokens, with a WWW-Authenticate: Bearer response header. Treat tokens like passwords.

Quick start

Start a job, then poll until it's done.

1. Start a job

curl -X POST https://api.youtubetotext.ai/v1/api/transcribe \
  -H "Authorization: Bearer ytt_<your-token>" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://youtube.com/watch?v=dQw4w9WgXcQ", "verbatim": false }'

2. Poll until done

curl https://api.youtubetotext.ai/v1/api/transcription/<id> \
  -H "Authorization: Bearer ytt_<your-token>"

When the state is "done", read the result field that matches the endpoint you called (see below). The same id works across all endpoints.

Endpoints

The job-creating endpoints and the one polling endpoint that serves them all.

  • POST/v1/api/transcribe

    Queue one video and get a job id back.

    Body: language_code, url*, verbatim

    Parameters and response

  • GET/v1/api/transcription/{id}

    Read a job: its state while it runs, its text when it is done.

    Parameters and response

  • POST/v1/api/subtitles

    Queue one video and get SRT and WebVTT cues back.

    Body: format, language_code, target_languages, url*, verbatim

    Parameters and response

  • POST/v1/api/burn-subtitles

    Queue one video and get a video with the captions rendered into it.

    Body: background, font_size, language_code, quality, target_languages, url*, verbatim

    Parameters and response

OpenAPI spec

The machine-readable version of this page.

Every endpoint above is described in openapi.json (OpenAPI 3.1). Import it into Postman, Insomnia or Bruno, or point a generator at it for a typed client in your own language. It is generated from the API and checked in with every release, so it stays in step with what the endpoints accept.

curl -O https://youtubetotext.ai/openapi.json

Typical flow

The same pattern for every job-creating endpoint.

  1. POST to the matching endpoint with the YouTube URL → store the returned id.
  2. Poll GET /v1/api/transcription/{id} every 2 to 3 seconds. Show state and progress (0 to 100) in your UI.
  3. When state is "done", read the result field for the mode you used:
    • transcribe txt
    • subtitles srt or webvtt
    • burn-subtitles burned_video_url
  4. If state is "failed", show error.

Errors

Every error body is {"detail": ...}.

  • 401: the token is missing, malformed or revoked. Send Authorization: Bearer ytt_<your-token>. Create or replace the token at /account/api/.
  • 404: no job or batch with that id on your account. Check the id came from a queue call made with the same token.
  • 422: the body did not validate. `detail` is an array, one entry per field, each naming the field in `loc`.
  • 429: too many requests. Back off and retry. Polling every 2 to 3 seconds stays well under it.

Notes

  • verbatim: true keeps filler words and exact phrasing. The default trims them.
  • A bad URL, a private video or an empty minute balance is not an HTTP error. The POST still answers 200 with an id; the job then ends with state: "failed" and a human-readable error. Only a malformed request answers before queueing: a missing url or an unknown value gives 422 with a detail array, one entry per field. A missing or invalid token answers 401.
  • The same id works across all endpoints. The job started by POST /transcribe is fetched by the same GET /transcription/{id}.

Need help?

Running into issues? Or do you have a question or a feature idea? Reach us through the contact page and we'll get back to you.

Pricing for the API

The API and MCP use the same plans and the same minutes as the site. A 10-minute video costs 10 minutes. Each translated subtitle language adds one video length. A burned-in video costs 3x the video length at 720p, 4x at 1080p and 5x at 4K. Every account starts with 10 free minutes.

Creator

Perfect for content creators

Not satisfied? We will refund your purchase, no questions asked.

Most popular

Creator+

For creators scaling their workflow

Not satisfied? We will refund your purchase, no questions asked.

Pro

Pro plan for agencies & power users

Not satisfied? We will refund your purchase, no questions asked.