REST API
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.
Prefer to ask Claude or ChatGPT instead of writing code? Use the MCP server.
Three steps. The token button above takes you to sign in first if you are not logged in, then straight to your token page.
Every account starts with 10 free minutes, no card needed. The API and MCP are included on every plan.
On the API page in your account. One token per account, shown once, revoke it there anytime.
Add it as an Authorization: Bearer header, POST a YouTube URL to /v1/api/transcribe and poll the job id until it is done.
Every endpoint, with the request and response you should expect. Stuck on something? Reach us through the contact page.
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.
Every endpoint requires a bearer token. Generate one on your API page and send it in the Authorization header.
Authorization: Bearer ytt_<your-token>
WWW-Authenticate: Bearer response header. Treat tokens like passwords.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.
The job-creating endpoints and the one polling endpoint that serves them all.
/v1/api/transcribeQueue one video and get a job id back.
Body: language_code, url*, verbatim
/v1/api/transcription/{id}Read a job: its state while it runs, its text when it is done.
/v1/api/subtitlesQueue one video and get SRT and WebVTT cues back.
Body: format, language_code, target_languages, url*, verbatim
/v1/api/burn-subtitlesQueue one video and get a video with the captions rendered into it.
Body: background, font_size, language_code, quality, target_languages, url*, verbatim
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
The same pattern for every job-creating endpoint.
id.GET /v1/api/transcription/{id} every 2 to 3 seconds. Show state and progress (0 to 100) in your UI.state is "done", read the result field for the mode you used:transcribe → txtsubtitles → srt or webvttburn-subtitles → burned_video_urlstate is "failed", show error.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.verbatim: true keeps filler words and exact phrasing. The default trims them.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.id works across all endpoints. The job started by POST /transcribe is fetched by the same GET /transcription/{id}.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.
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.