# TranscriptAPI > REST API and MCP server for YouTube transcripts, search, channel and playlist listings. No YouTube Data API quota, no OAuth, no scraping infrastructure of your own. Base URL: https://api.transcriptapi.io — auth: `Authorization: Bearer ta_…`. New accounts get 20 free credits (https://transcriptapi.io/login), one credit per successful call, cached repeats free. This file is written for AI assistants that are helping a developer integrate TranscriptAPI. Everything below is current; when in doubt the OpenAPI spec at https://api.transcriptapi.io/openapi.json is authoritative. ## Quick facts - Base URL: `https://api.transcriptapi.io` - Auth: HTTP header `Authorization: Bearer `; keys start with `ta_` - All endpoints are GET with query parameters and return JSON, except webhook subscribe (POST/DELETE) - Cost: 1 credit per successful, uncached call. Translation adds 1 credit per 40 transcript segments (minimum 2). Cache hits cost 0. - Failures caused by the video (captions disabled, private, deleted, age-restricted) are **refunded automatically** and return HTTP 404 with `retryable: false`. Do not retry those. - HTTP 503 with `retryable: true` means a transient upstream problem — retry with backoff. - HTTP 402 = out of credits. HTTP 401 = bad key. HTTP 422 = malformed input (e.g. a template placeholder like `{{ video_id }}` sent literally). - Video ids are the 11-character id from a watch URL (`dQw4w9WgXcQ`). Send the id, not the URL. ## Endpoints ### GET /transcript — transcript of one video Query: `video_id` (required), `language` (default `en`, e.g. `de`, `es`), `translate_to` (optional, AI translation into a language code; extra credits). Response: ```json { "video_id": "dQw4w9WgXcQ", "transcript": [ { "start": 1.2, "duration": 2.16, "text": "All right, so here we are" } ] } ``` With `translate_to` the response also carries `"translated_to": "de"`. `start` and `duration` are seconds. Join `text` fields for prose; use `start` for timestamps or SRT/VTT. ### GET /search — search YouTube Query: `q` (required), `limit` (default 20). Response: `{ "query": "...", "results": [ { "id", "title", "channel", "views", "duration" } ] }` ### GET /channel/videos — a channel's latest uploads Query: `channel_id` (required — a `UC…` id **or** an `@handle`), `limit` (default 50). Response: `{ "channel_id", "title", "total", "videos": [ { "id", "title", "views", "duration", "published" } ] }` ### GET /channel/search — keyword search inside one channel Query: `channel_id` (required), `q` (required), `limit` (default 20). Response: `{ "channel_id", "query", "results": [ { "id", "title", "channel", "views", "duration" } ] }` ### GET /playlist — a playlist's videos Query: `playlist_id` (required, the `list=` value), `limit` (default 100). Response: `{ "playlist_id", "total", "videos": [ { "id", "title", ... } ] }` ### POST /channel/subscribe — webhook on new uploads JSON body: `{ "channel_id": "UC…", "webhook_url": "https://…" }`. `DELETE /channel/subscribe?channel_id=UC…` removes it. TranscriptAPI calls the webhook when the channel publishes a new video, so a transcript can be fetched the moment it exists. ### GET /health — liveness, no auth ## Error shape ```json { "detail": "This video has captions disabled by the uploader. Your credits have been refunded.", "error": "TranscriptsDisabled", "hint": "Retrying will not help. There is no caption track to fetch.", "retryable": false, "credits_refunded": 1 } ``` `detail` is always a human-readable string. Branch on `retryable`, not on the text. ## Examples curl: ```bash curl "https://api.transcriptapi.io/transcript?video_id=dQw4w9WgXcQ&language=en" \ -H "Authorization: Bearer $TRANSCRIPTAPI_KEY" ``` Python: ```python import requests, os r = requests.get("https://api.transcriptapi.io/transcript", params={"video_id": "dQw4w9WgXcQ"}, headers={"Authorization": f"Bearer {os.environ['TRANSCRIPTAPI_KEY']}"}) r.raise_for_status() text = " ".join(s["text"] for s in r.json()["transcript"]) ``` JavaScript: ```js const res = await fetch("https://api.transcriptapi.io/transcript?video_id=dQw4w9WgXcQ", { headers: { Authorization: `Bearer ${process.env.TRANSCRIPTAPI_KEY}` }, }); if (!res.ok) { const e = await res.json(); if (!e.retryable) throw new Error(e.detail); } const { transcript } = await res.json(); ``` ## MCP server (for Claude, Cursor, VS Code, Windsurf and other MCP clients) Package: `transcriptapi-mcp` on npm (stdio transport, Node 18+). Tools: `get_youtube_transcript`, `search_youtube`, `get_channel_videos`, `search_channel_videos`, `get_playlist_videos`; prompt `summarize_youtube_video`. Tools accept full YouTube URLs, Shorts links, `@handles` and playlist URLs and extract ids themselves. Claude Desktop / Cursor / Windsurf config (`mcpServers`), VS Code uses `servers` and `"type": "stdio"`: ```json { "mcpServers": { "transcriptapi": { "command": "npx", "args": ["-y", "transcriptapi-mcp"], "env": { "TRANSCRIPTAPI_KEY": "ta_your_key" } } } } ``` Claude Code (local): `claude mcp add transcriptapi -e TRANSCRIPTAPI_KEY=ta_your_key -- npx -y transcriptapi-mcp` Hosted endpoint (Streamable HTTP, same tools, nothing to install): `https://api.transcriptapi.io/mcp` - claude.ai / ChatGPT connectors (cannot send headers): use `https://api.transcriptapi.io/mcp/ta_your_key` as the URL, authentication "none" - Claude Code: `claude mcp add --transport http transcriptapi https://api.transcriptapi.io/mcp --header "Authorization: Bearer ta_your_key"` - Cursor / VS Code / Windsurf: `{ "url": "https://api.transcriptapi.io/mcp", "headers": { "Authorization": "Bearer ta_your_key" } }` Guide: https://transcriptapi.io/mcp ## Pricing 20 free credits at signup, no card. Pay-as-you-go packs: 2,500 credits $10 · 10,000 $39 · 50,000 $149 · 200,000 $449. Credits do not expire. https://transcriptapi.io/#pricing ## Links - [API reference](https://transcriptapi.io/docs): every endpoint with parameters, credit cost and live response examples - [OpenAPI spec](https://api.transcriptapi.io/openapi.json): machine-readable schema - [Cookbook](https://transcriptapi.io/cookbook): working recipes — bulk channel export, SRT generation, n8n/Make/Zapier - [MCP server](https://transcriptapi.io/mcp): setup for Claude Desktop, Claude Code, Cursor, VS Code, Windsurf - [Migration guide](https://transcriptapi.io/migrate): moving from youtube-transcript-api, Supadata, or the YouTube Data API - [Free tools](https://transcriptapi.io/tools): transcript, SRT, summary, translation, channel and playlist tools that need no key - [Dashboard](https://transcriptapi.io/dashboard): key, credits, usage - [Discord](https://discord.gg/gvAwUZQCfX): support, usually within the hour