youtube-captions-api
v1.0.1
Published
Reliable YouTube transcript fetcher for Node.js — port of the popular Python youtube-transcript-api (2025 edition)
Maintainers
Readme
youtube-captions-api
A reliable, self-contained Node.js/TypeScript port of the popular Python youtube-transcript-api (as of December 2025).
This is mostly an AI-generated port (created with assistance from Grok by xAI), faithfully replicating the Python library's core logic, error handling, consent handling, and reliability.
Fetches timed transcripts (manual or auto-generated) using YouTube's internal Innertube API — no official API key required.
Warning: This uses undocumented endpoints. It may break if YouTube changes their internals.
Features
- Instance-based API (
new YouTubeTranscriptApi()) fetch(videoIdOrUrl, { languages })→ timed segments with start/duration- Language priority (prefers manual captions over auto-generated)
- Consent cookie handling
- Proxy support for production/cloud use
- Full concatenated text via
.getText() - Debug logging of transcript URL
- Minimal dependencies (only
undici)
Installation
npm install youtube-captions-apiUsage
import YouTubeTranscriptApi from 'youtube-captions-api';
(async () => {
try {
// Optional: use a residential proxy for cloud deployments (highly recommended)
// const api = new YouTubeTranscriptApi('http://user:pass@residential-ip:port');
const api = new YouTubeTranscriptApi();
const transcript = await api.fetch('dQw4w9WgXcQ', {
languages: ['en'], // priority list – falls back automatically
});
// First timed segment
console.log(transcript.snippets[0]);
// → { text: "We're no strangers to love", start: 12.5, duration: 3.2 }
// Full concatenated text
console.log(transcript.getText());
// Metadata
console.log('Language:', transcript.language_code);
console.log('Auto-generated:', transcript.is_generated);
console.log('Segments count:', transcript.snippets.length);
} catch (err) {
console.error(err instanceof Error ? err.message : err);
}
})();Express Server Example
See server.js in the repo for a ready-to-run API endpoint:
GET /transcript?id=dQw4w9WgXcQ
→ { video_id, text, language, timed_segments: [{ timestamp, seconds, text }, ...] }Run:
npm run build
node server.jsTest: http://localhost:3000/transcript?id=dQw4w9WgXcQ
Production Notes
- Works reliably locally on residential IPs.
- In cloud/server environments, YouTube frequently blocks datacenter IPs → use rotating residential proxies (e.g., Webshare, Bright Data, Oxylabs).
- Simply pass the proxy URL to the constructor when deploying.
License
MIT
Inspired by the excellent Python original — huge thanks to jdepoix!
