transcriptfetchGitHubDashboard
SDKs

Node SDK

The official, typed Node.js / TypeScript client. Fetch transcripts, channels, playlists, and search as structured data, ESM + CommonJS, zero runtime dependencies.

Official SDK. Source + issues on GitHub. Your key falls back to the TRANSCRIPTFETCH_API_KEY env var, keep it server-side. One credit per successful fetch; failed/blocked/no-transcript requests are free.
Using n8n? There is a community node that wraps this API for n8n workflows, no code required: n8n-nodes-transcriptfetch.

Install

bash
npm install transcriptfetch

Requires Node 18+ (uses the built-in fetch). Ships types for TypeScript.

Quickstart

Get an API key (100 free credits a month) at the dashboard, then:

TypeScript
import { TranscriptFetch } from "transcriptfetch";

// apiKey falls back to the TRANSCRIPTFETCH_API_KEY env var
const tf = new TranscriptFetch("tf_live_...");

const t = await tf.transcripts.video("https://youtu.be/aircAruvnKk");
console.log(t.title);
console.log(t.text);
for (const seg of t.segments) {
  console.log(`[${seg.start.toFixed(1)}] ${seg.text}`);
}

console.log("credits left:", t.usage?.balance);

Endpoints

video/channel/playlist accept URLs or raw IDs (normalized automatically).

TypeScript
await tf.transcripts.video(video);                          // single transcript (text + segments)
await tf.transcripts.channel(channel, { limit, cursor });   // a channel's videos (metadata)
await tf.transcripts.playlist(playlist, { limit, cursor }); // a playlist's videos
await tf.transcripts.search(query, { limit, cursor });      // search YouTube
await tf.transcripts.batch(videoIds);                       // up to 50 transcripts in one call
await tf.health();                                          // unauthenticated liveness probe

Pagination

List endpoints are cursor-paginated. Iterate every result with an async generator:

TypeScript
// Iterate every result without managing cursors
for await (const video of tf.transcripts.iterChannel("@lexfridman", { limit: 10 })) {
  console.log(video.videoId, video.title);
}

// ...or page manually via page.nextCursor and the cursor option.

Errors

All errors subclass TranscriptFetchError. API errors carry .status, .code, .message, and .requestId.

TypeScript
import {
  InsufficientCreditsError, RateLimitError, APIError,
} from "transcriptfetch";

try {
  await tf.transcripts.video("bad");
} catch (err) {
  if (err instanceof InsufficientCreditsError) {
    // 402: top up at /pricing
  } else if (err instanceof RateLimitError) {
    console.log(err.retryAfter);            // 429
  } else if (err instanceof APIError) {
    console.log(err.status, err.code, err.requestId);
  }
}
Reliability built in. Automatic retries on 429 (honoring Retry-After) and 5xx with exponential backoff; every write auto-sends an Idempotency-Key so a retried request is never double-charged. Configure via new TranscriptFetch({ apiKey, baseUrl, timeout: 30000, maxRetries: 2 }).

Prefer raw HTTP? The API is plain HTTPS/JSON, see the endpoint reference for every route and the response format.

Next →Back to Quickstart
Node SDK · TranscriptFetch docs