Skip to content

Commit e8fa48c

Browse files
author
Transcript-Fetch-Admin
committed
docs: README and runnable examples
1 parent 02925df commit e8fa48c

4 files changed

Lines changed: 138 additions & 0 deletions

File tree

‎README.md‎

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# TranscriptFetch Node.js SDK
2+
3+
The official Node.js / TypeScript client for the [TranscriptFetch API](https://transcriptfetch.com). Fetch YouTube transcripts, channels, playlists, and search as clean, typed data, with built-in retries, idempotency, and a typed error hierarchy.
4+
5+
- Typed responses (full TypeScript types, ESM + CommonJS)
6+
- Automatic retries on 429 and 5xx with backoff
7+
- Auto-generated idempotency keys on writes
8+
- Auto-paginating async iterators
9+
- Zero runtime dependencies (uses the built-in `fetch`, Node 18+)
10+
11+
## Install
12+
13+
```bash
14+
npm install transcriptfetch
15+
```
16+
17+
## Quickstart
18+
19+
```ts
20+
import { TranscriptFetch } from "transcriptfetch";
21+
22+
// apiKey falls back to the TRANSCRIPTFETCH_API_KEY env var
23+
const tf = new TranscriptFetch("tf_live_...");
24+
25+
const t = await tf.transcripts.video("https://youtu.be/aircAruvnKk");
26+
console.log(t.title);
27+
console.log(t.text);
28+
for (const seg of t.segments) {
29+
console.log(`[${seg.start.toFixed(1)}] ${seg.text}`);
30+
}
31+
32+
console.log("credits left:", t.usage?.balance);
33+
```
34+
35+
Keep your key server-side. Never ship it to the browser.
36+
37+
## Endpoints
38+
39+
```ts
40+
await tf.transcripts.video(video); // single transcript (text + segments)
41+
await tf.transcripts.channel(channel, { limit, cursor }); // a channel's videos (metadata)
42+
await tf.transcripts.playlist(playlist, { limit, cursor }); // a playlist's videos
43+
await tf.transcripts.search(query, { limit, cursor }); // search YouTube
44+
await tf.transcripts.batch(videoIds); // up to 50 transcripts in one call
45+
await tf.health(); // unauthenticated liveness probe
46+
```
47+
48+
## Pagination
49+
50+
Skip cursor bookkeeping with the auto-paginating iterators:
51+
52+
```ts
53+
for await (const video of tf.transcripts.iterChannel("@lexfridman", { limit: 10 })) {
54+
console.log(video.videoId, video.title);
55+
}
56+
```
57+
58+
Or page manually via `page.nextCursor` and the `cursor` option.
59+
60+
## Errors
61+
62+
Every failure maps to a typed subclass so you can branch with `instanceof`:
63+
64+
```ts
65+
import {
66+
TranscriptFetch,
67+
InsufficientCreditsError,
68+
RateLimitError,
69+
APIError,
70+
} from "transcriptfetch";
71+
72+
try {
73+
await tf.transcripts.video("bad");
74+
} catch (err) {
75+
if (err instanceof InsufficientCreditsError) {
76+
// 402: top up at /pricing
77+
} else if (err instanceof RateLimitError) {
78+
console.log("retry after", err.retryAfter); // 429
79+
} else if (err instanceof APIError) {
80+
console.log(err.status, err.code, err.requestId);
81+
}
82+
}
83+
```
84+
85+
The full hierarchy: `AuthenticationError`, `InvalidRequestError`, `InsufficientCreditsError`, `IdempotencyConflictError`, `RateLimitError`, `UpstreamUnavailableError`, `InternalServerError` (all extend `APIError`), plus `APIConnectionError` and `APITimeoutError` for transport failures. All extend `TranscriptFetchError`.
86+
87+
## Configuration
88+
89+
```ts
90+
const tf = new TranscriptFetch({
91+
apiKey: "tf_live_...", // or TRANSCRIPTFETCH_API_KEY
92+
baseUrl: "https://transcriptfetch.com",
93+
timeout: 30_000, // ms
94+
maxRetries: 2, // retries 429 + 5xx
95+
});
96+
```
97+
98+
## Links
99+
100+
- API docs: https://transcriptfetch.com/docs
101+
- Python SDK: https://github.com/TranscriptFetch/python-sdk
102+
103+
## License
104+
105+
MIT

‎examples/batch.mjs‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Batch: fetch up to 50 transcripts in one call.
2+
// Run: TRANSCRIPTFETCH_API_KEY=tf_live_... node examples/batch.mjs
3+
import { TranscriptFetch } from "transcriptfetch";
4+
5+
const tf = new TranscriptFetch();
6+
7+
const res = await tf.transcripts.batch(["dQw4w9WgXcQ", "9bZkp7q19f0"]);
8+
for (const r of res.results) {
9+
console.log(r.videoId, r.outcome, r.text ? `${r.text.length} chars` : "(no text)");
10+
}
11+
console.log("credits spent:", res.usage?.creditsSpent);

‎examples/paginate.mjs‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Pagination: iterate every video in a channel without managing cursors.
2+
// Run: TRANSCRIPTFETCH_API_KEY=tf_live_... node examples/paginate.mjs
3+
import { TranscriptFetch } from "transcriptfetch";
4+
5+
const tf = new TranscriptFetch();
6+
7+
let count = 0;
8+
for await (const video of tf.transcripts.iterChannel("@lexfridman", { limit: 10 })) {
9+
console.log(video.videoId, video.title);
10+
if (++count >= 30) break; // stop early for the demo
11+
}

‎examples/quickstart.mjs‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Quickstart: fetch a single transcript.
2+
// Run: TRANSCRIPTFETCH_API_KEY=tf_live_... node examples/quickstart.mjs
3+
import { TranscriptFetch } from "transcriptfetch";
4+
5+
const tf = new TranscriptFetch();
6+
7+
const t = await tf.transcripts.video("https://youtu.be/aircAruvnKk");
8+
console.log(t.title);
9+
console.log(t.text?.slice(0, 200), "...");
10+
console.log("segments:", t.segments.length);
11+
console.log("credits left:", t.usage?.balance);

0 commit comments

Comments
 (0)