Production-ready YouTube Transcript API. Extract transcripts from any video with a single REST call. Python, JavaScript, and PHP SDKs. 150 free requests, <1.5s response time, 99.9% uptime.

The YouTubeTranscripts.co API lets you extract transcripts from any YouTube video with a single HTTP request. Unlike the open-source youtube-transcript-api Python package, this is a hosted API that works in production — no IP blocks, no proxy rotation, no YouTube anti-bot issues. Send a video URL, get back structured transcript data in under 1.5 seconds. SDKs available for Python, JavaScript, and PHP. 150 free requests included, no credit card required.
Three lines of code. That is all it takes to extract a YouTube transcript. Choose your language below.
# ─── curl ───────────────────────────────────────────────────
curl -X POST "https://api.youtubetranscripts.co/v1/transcript" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://youtube.com/watch?v=dQw4w9WgXcQ"}'
# ─── Python ─────────────────────────────────────────────────
pip install youtubetranscripts
from youtubetranscripts import YouTubeTranscripts
client = YouTubeTranscripts(api_key="YOUR_API_KEY")
transcript = client.get_transcript("https://youtube.com/watch?v=dQw4w9WgXcQ")
print(transcript.text) # Full text
print(transcript.word_count) # 438
print(transcript.lang) # "en"
for segment in transcript.content:
print(f"[{segment.offset_ms}ms] {segment.text}")
# ─── JavaScript / Node.js ──────────────────────────────────
npm install youtubetranscripts
import { YouTubeTranscripts } from "youtubetranscripts";
const client = new YouTubeTranscripts({ apiKey: "YOUR_API_KEY" });
const transcript = await client.getTranscript(
"https://youtube.com/watch?v=dQw4w9WgXcQ"
);
console.log(transcript.text); // Full text
console.log(transcript.wordCount); // 438
transcript.content.forEach((seg) => {
console.log(`[${seg.offsetMs}ms] ${seg.text}`);
});
# ─── PHP ────────────────────────────────────────────────────
composer require youtubetranscripts/youtubetranscripts-php
use YouTubeTranscripts\Client;
$client = new Client('YOUR_API_KEY');
$transcript = $client->getTranscript('https://youtube.com/watch?v=dQw4w9WgXcQ');
echo $transcript->text;
echo $transcript->wordCount; // 438/v1/transcript{
"video_id": "dQw4w9WgXcQ",
"title": "Rick Astley - Never Gonna Give You Up",
"lang": "en",
"source": "caption_auto",
"word_count": 438,
"duration_ms": 213000,
"requests_used": 1,
"balance_remaining": 149,
"content": [
{ "text": "Never gonna give you up", "offset_ms": 18400, "duration_ms": 2040 },
{ "text": "Never gonna let you down", "offset_ms": 20440, "duration_ms": 1660 },
{ "text": "Never gonna run around", "offset_ms": 22100, "duration_ms": 1700 },
{ "text": "and desert you", "offset_ms": 23800, "duration_ms": 1400 }
]
}The YouTubeTranscripts.co API has three endpoints. All requests use the x-api-key header for authentication and return JSON responses.
# POST /v1/transcript — Request body parameters
{
"url": "string", # Required. YouTube video URL or video ID.
"lang": "string", # Optional. Language code (e.g., "en", "es", "ja"). Auto-detected if omitted.
"format": "string", # Optional. "json" (default), "text", "srt", "vtt".
"ai_fallback": true, # Optional. Enable Whisper AI for uncaptioned videos. Default: true.
"preserve_formatting": false # Optional. Keep line breaks from original captions. Default: false.
}
# POST /v1/transcript/batch — Request body
{
"urls": ["string"], # Required. Array of 1-25 YouTube URLs.
"lang": "string", # Optional. Applied to all videos.
"format": "string" # Optional. Applied to all videos.
}
# Response headers (all endpoints)
# X-RateLimit-Limit: 60 (requests per minute)
# X-RateLimit-Remaining: 58 (remaining in current window)
# X-RateLimit-Reset: 1714200000 (Unix timestamp when window resets)| Endpoint | Method | Description | Auth Required |
|---|---|---|---|
| /v1/transcript | POST | Extract transcript from a single YouTube video | Yes |
| /v1/transcript/batch | POST | Extract transcripts from up to 25 videos in one request | Yes |
| /v1/account | GET | Check API key status, remaining balance, and usage stats | Yes |
Official SDKs wrap the REST API with typed responses, automatic retries, and error handling. Install with a single command.
# Python (PyPI)
pip install youtubetranscripts
# JavaScript / TypeScript (npm)
npm install youtubetranscripts
# PHP (Composer)
composer require youtubetranscripts/youtubetranscripts-php| SDK | Package Manager | Min Version | Typed Responses |
|---|---|---|---|
| Python | pip (PyPI) | Python 3.8+ | Yes (dataclasses) |
| JavaScript | npm | Node.js 18+ | Yes (TypeScript) |
| PHP | Composer (Packagist) | PHP 8.1+ | Yes (typed classes) |
All API requests require an API key passed in the x-api-key header. Keys are free and created instantly at youtubetranscripts.co/login.
Sign up at youtubetranscripts.co/login with email or Google. Your API key is generated instantly — no approval process, no credit card. Copy it from the dashboard.
Include the header x-api-key: YOUR_API_KEY on every request. The key is a 32-character alphanumeric string. Store it in environment variables — never commit it to source control.
Every response includes requests_used and balance_remaining fields. Use GET /v1/account to check your current balance, usage history, and rate limit status at any time.
| Plan | Requests | Rate Limit | Price | AI Fallback |
|---|---|---|---|---|
| Free | 150 | 60/min | $0 | Yes |
| Starter | 500 | 120/min | $5 | Yes |
| Pro | 2,500 | 300/min | $20 | Yes |
| Business | 10,000 | 600/min | $65 | Yes |
| Enterprise | Custom | Custom | Contact us | Yes + priority |
No monthly subscriptions. Buy credits when you need them, and they never expire. Every plan includes full API access, all output formats, AI fallback, and batch processing.
Buy once, use whenever. No monthly billing, no auto-renewal, no wasted credits at the end of the month.
Every plan — including Free — gets full API access, all output formats, AI fallback, batch processing, and all three SDKs. No feature gating.
A batch request with 25 URLs uses 25 credits — one per video. The batch endpoint itself does not cost extra.
| Plan | Requests | Cost per Request | Total Price | Best For |
|---|---|---|---|---|
| Free | 150 | $0.000 | $0 | Testing and prototyping |
| Starter | 500 | $0.010 | $5 | Side projects, MVPs |
| Pro | 2,500 | $0.008 | $20 | Production apps, SaaS integrations |
| Business | 10,000 | $0.0065 | $65 | High-volume pipelines |
| Enterprise | 50,000+ | $0.004 | Custom | Media companies, AI platforms |
Developers evaluating transcript APIs typically compare three options: our hosted API, the open-source youtube-transcript-api Python package, and Supadata's API. Here is an honest comparison.
| Feature | YouTubeTranscripts.co | youtube-transcript-api | Supadata |
|---|---|---|---|
| Type | Hosted REST API | Python library (local) | Hosted REST API |
| Works in production | Yes | No (IP blocked on cloud) | Yes |
| AI fallback | Yes (Whisper) | No | Yes |
| SDKs | Python, JS, PHP | Python only | Python, JS |
| Batch endpoint | 25 videos/request | No | Yes |
| Free tier | 150 requests | Unlimited (local only) | 100 requests |
| Response time | <1.5s | Depends on connection | ~2s |
| Rate limit (free) | 60/min | N/A | 30/min |
| Cost per request | From $0.004 | Free (self-hosted) | From $0.005 |
The API returns standard HTTP status codes and structured error responses. Every error includes a machine-readable code and a human-readable message.
# Error response format
{
"error": {
"code": "INSUFFICIENT_BALANCE",
"message": "Your account has 0 remaining requests. Purchase credits at youtubetranscripts.co/pricing",
"status": 402
}
}
# Python SDK — error handling
from youtubetranscripts import YouTubeTranscripts, APIError, RateLimitError
client = YouTubeTranscripts(api_key="YOUR_API_KEY")
try:
transcript = client.get_transcript("https://youtube.com/watch?v=VIDEO_ID")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after} seconds.")
except APIError as e:
print(f"API error {e.status}: {e.code} — {e.message}")| Status Code | Error Code | Description | Resolution |
|---|---|---|---|
| 400 | INVALID_URL | The URL is not a valid YouTube video link | Check URL format — must be youtube.com/watch?v= or youtu.be/ |
| 401 | INVALID_API_KEY | API key is missing or invalid | Check x-api-key header. Get a key at youtubetranscripts.co/login |
| 402 | INSUFFICIENT_BALANCE | No remaining credits on your account | Purchase additional credits at youtubetranscripts.co/pricing |
| 404 | VIDEO_NOT_FOUND | The video does not exist or is private | Verify the video ID. Private videos cannot be accessed. |
| 429 | RATE_LIMITED | Too many requests in the current minute | Wait until X-RateLimit-Reset. Implement exponential backoff. |
| 500 | INTERNAL_ERROR | Server error during transcript extraction | Retry after 5 seconds. If persistent, contact support. |
Sign up at youtubetranscripts.co/login with your email or Google account. Your API key is generated instantly — no approval process, no credit card required. You start with 150 free requests. Copy the key from your dashboard and pass it in the x-api-key header.
The youtube-transcript-api Python package is an open-source library that calls YouTube directly from your server. It works on localhost but gets IP-blocked when deployed to cloud services (AWS, GCP, Vercel, Railway). YouTubeTranscripts.co is a hosted API that handles proxy rotation and anti-bot measures — your production app never breaks.
The free tier includes 150 requests with no credit card. Paid plans start at $5 for 500 requests ($0.01/request). Volume discounts bring the cost down to $0.004/request at the Enterprise tier. Credits never expire — no monthly billing.
The free tier allows 60 requests per minute. Paid plans scale up to 600/min (Business) and custom limits (Enterprise). Rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset) are included in every response so you can implement backoff logic.
Yes. POST to /v1/transcript/batch with an array of up to 25 YouTube URLs. All videos are processed in parallel. Each video costs 1 credit. The response is a JSON array with one result per video, including any errors for individual URLs.
The API supports 100+ languages. Language is auto-detected from the video's available captions. You can override this with the lang parameter (ISO 639-1 codes: 'en', 'es', 'ja', 'de', etc.). AI fallback via Whisper supports the same 100+ languages.
Yes. When ai_fallback is enabled (the default), the API uses OpenAI Whisper to transcribe the audio of uncaptioned videos. The response includes source: 'ai_generated' so you know which method was used. AI transcription adds 5-15 seconds to response time.
Official SDKs exist for Python (pip install youtubetranscripts), JavaScript/TypeScript (npm install youtubetranscripts), and PHP (composer require youtubetranscripts/youtubetranscripts-php). All SDKs provide typed responses, automatic retries on 429/500 errors, and batch support.
Implement exponential backoff for 429 (rate limit) and 500 (server error) responses. The SDKs handle this automatically with 3 retries. Check the X-RateLimit-Remaining header to proactively throttle requests before hitting the limit. Use the /v1/account endpoint to monitor your credit balance.
Yes. The API is designed for integration into production applications. Business and Enterprise plans offer the throughput needed for SaaS products. There are no restrictions on commercial use. If you need a custom rate limit, SLA, or dedicated infrastructure, contact us for an Enterprise plan.
Get transcripts with Python in 3 lines of code
Extract transcripts with Node.js and TypeScript
Get any video's full text instantly
Free online transcription tool
Generate transcripts with no signup
Extract full text from any YouTube video
150 free requests. No credit card. Python, JavaScript, and PHP SDKs. Get your API key in 30 seconds.