npm package: @namaki/youtube-transcript-ts
Description: Fetch YouTube video transcripts via the Innertube API
Latest version: 1.0.4

# youtube-transcript-ts

Fetch YouTube video transcripts via the Innertube API. TypeScript port of [jdepoix/youtube-transcript-api](https://github.com/jdepoix/youtube-transcript-api).

## Install

```bash
npm install @namaki/youtube-transcript-ts
```

## Usage

### Fetch a transcript

```ts
import { getTranscript } from "@namaki/youtube-transcript-ts"

const result = await getTranscript({ videoId: "dQw4w9WgXcQ" })

if (result.ok) {
  console.log(result.language)       // "en"
  console.log(result.autoGenerated)  // true
  console.log(result.data)
  // [{ text: "Never gonna give you up", start: 18.0, duration: 3.2 }, ...]
}
```

### Accept full URLs

`videoId` accepts raw 11-character IDs or full YouTube URLs:

```ts
await getTranscript({ videoId: "https://www.youtube.com/watch?v=dQw4w9WgXcQ" })
await getTranscript({ videoId: "https://youtu.be/dQw4w9WgXcQ" })
await getTranscript({ videoId: "https://www.youtube.com/shorts/dQw4w9WgXcQ" })
```

### Request a specific language

```ts
const result = await getTranscript({ videoId: "dQw4w9WgXcQ", lang: "es" })
```

### Text only (no timestamps)

```ts
const result = await getTranscript({ videoId: "dQw4w9WgXcQ", timestamps: false })
// result.data = [{ text: "Never gonna give you up" }, ...]
```

### List available languages

```ts
import { listAvailableLanguages } from "@namaki/youtube-transcript-ts"

const result = await listAvailableLanguages("dQw4w9WgXcQ")

if (result.ok) {
  console.log(result.data)
  // [{ code: "en", name: "English", autoGenerated: true }, ...]
}
```

### Parse raw json3 data

If you already have cached or proxied json3 caption data:

```ts
import { parseJson3 } from "@namaki/youtube-transcript-ts"

const segments = parseJson3(json3Data, true)
// [{ text: "Hello", start: 1.0, duration: 2.0 }, ...]
```

### Extract a video ID from a URL

```ts
import { parseVideoId } from "@namaki/youtube-transcript-ts"

parseVideoId("https://www.youtube.com/watch?v=dQw4w9WgXcQ") // "dQw4w9WgXcQ"
parseVideoId("https://youtu.be/dQw4w9WgXcQ")                // "dQw4w9WgXcQ"
parseVideoId("bad-input")                                     // null
```

## Error handling

This library uses result unions instead of thrown exceptions. Every function returns `{ ok: true, ... }` on success or `{ ok: false, code, message }` on failure. TypeScript's type narrowing guides you to handle all cases:

```ts
const result = await getTranscript({ videoId: "dQw4w9WgXcQ" })

if (!result.ok) {
  switch (result.code) {
    case "INVALID_VIDEO_ID":
      // The input wasn't a valid video ID or YouTube URL
      break
    case "NO_CAPTIONS":
      // The video has no caption tracks
      break
    case "LANG_NOT_AVAILABLE":
      // The requested language doesn't exist for this video
      break
    case "FETCH_FAILED":
      // Network error or unexpected HTTP status
      break
  }
  return
}

// result.ok is true — result.data, result.language, result.autoGenerated are available
```

## API

### `getTranscript(options): Promise<TranscriptResult>`

| Option | Type | Default | Description |
|---|---|---|---|
| `videoId` | `string` | required | Video ID or full YouTube URL |
| `lang` | `string` | first available | Language code (e.g. `"en"`, `"es"`) |
| `timestamps` | `boolean` | `true` | Include `start` and `duration` on segments |

### `listAvailableLanguages(videoId): Promise<LanguageListResult>`

Returns available caption tracks for a video. Each entry has `code`, `name`, and `autoGenerated`.

### `parseJson3(data, timestamps): TranscriptSegment[]`

Parses YouTube's json3 caption format into transcript segments.

### `parseVideoId(input): string | null`

Extracts an 11-character video ID from a raw ID or YouTube URL. Returns `null` if invalid.

## Types

```ts
type TranscriptSegment = {
  text: string
  start?: number
  duration?: number
}

type TranscriptSuccess = {
  ok: true
  code: "TRANSCRIPT_FOUND"
  data: TranscriptSegment[]
  language: string
  autoGenerated: boolean
}

type TranscriptError = {
  ok: false
  code: "NO_CAPTIONS" | "LANG_NOT_AVAILABLE" | "FETCH_FAILED" | "INVALID_VIDEO_ID"
  message: string
}

type LanguageInfo = {
  code: string
  name: string
  autoGenerated: boolean
}
```

## Disclaimer

This library uses YouTube's internal Innertube API, which is **not a publicly documented or supported API**. It may break without notice if YouTube changes its internal endpoints or data formats.

This project is not affiliated with, endorsed by, or sponsored by YouTube or Google. Use of this library may be subject to [YouTube's Terms of Service](https://www.youtube.com/t/terms). It is your responsibility to ensure that your use complies with all applicable terms, policies, and laws — including copyright and data protection regulations.

This library is provided "as is" with no warranty. The authors are not liable for any damages or legal consequences arising from its use. **Use at your own risk.**

## License

MIT