> ## Documentation Index
> Fetch the complete documentation index at: https://docs.particle.pro/llms.txt
> Use this file to discover all available pages before exploring further.

# Transcripts

> Diarized dialogue, word-level timestamps, entity mentions in context, and SRT export.

Every transcribed episode has three transcript views, each tuned for a different use case:

* **Dialogue** — speaker-attributed lines with sentence-level timestamps. The default. Best for chat-style UIs, LLM context windows, and most reading.
* **Words** — every word individually timestamped. Best for karaoke-style highlighting, precision audio editing, and word-aligned search.
* **Mentions** — lines surrounding mentions of a specific entity, with `is_mention` flags. Best for "what did they say about X?" workflows.

Dialogue transcripts are also reachable scoped to a single segment or clip.

<Note>Available to MCP agents via [`particle_podcast_get_episode`](/mcp/tools/podcasts/podcast-get-episode) with `include: ["transcript"]` (and optional `transcript_format`, `transcript_speaker`, `transcript_start`, `transcript_end`). For mention-style windows, use [`particle_podcast_find_mentions`](/mcp/tools/podcasts/podcast-find-mentions).</Note>

## Dialogue transcript

<CodeGroup>
  ```bash curl theme={"dark"}
  curl "https://api.particle.pro/v1/podcasts/episodes/78cgekLUjCJBUZbj3s5K8Y/transcript" \
    -H "X-API-Key: $PARTICLE_API_KEY"
  ```

  ```js JavaScript theme={"dark"}
  const res = await fetch(
    "https://api.particle.pro/v1/podcasts/episodes/78cgekLUjCJBUZbj3s5K8Y/transcript",
    { headers: { "X-API-Key": process.env.PARTICLE_API_KEY } },
  );
  const { lines } = await res.json();
  ```
</CodeGroup>

```jsonc Response (truncated) theme={"dark"}
{
  "episode_id": "78cgekLUjCJBUZbj3s5K8Y",
  "language": "en",
  "duration_seconds": 4206,
  "lines": [
    {
      "number": 1,
      "speaker": "Scott Galloway",
      "role": "CO_HOST",
      "start_seconds": 0.56,
      "end_seconds": 7.74,
      "text": "This episode is brought to you by The Build Podcast…"
    }
    // …
  ]
}
```

Lines are ordered, 1-indexed, and include speaker name and role. Note that the first lines of many episodes are sponsorship reads — fetch `/segments` to see which time ranges are tagged `AD` if you want to skip them. See [segments](/podcasts/segments-and-clips#segments).

## Output formats

Use the `format` query parameter:

<Tabs>
  <Tab title="Dialogue (default)" icon="comments">
    Structured JSON with speaker attribution, roles, and timestamps per line.

    ```bash theme={"dark"}
    curl ".../transcript?format=dialogue"
    ```

    Best for: building conversation UIs, speaker analysis, programmatic processing.
  </Tab>

  <Tab title="Plain text" icon="align-left">
    `Speaker: text` lines, one per turn.

    ```bash theme={"dark"}
    curl ".../transcript?format=text"
    ```

    Best for: LLM context windows, full-text display, search indexing.
  </Tab>

  <Tab title="SRT subtitles" icon="closed-captioning">
    Standard SubRip format with speaker labels.

    ```bash theme={"dark"}
    curl ".../transcript?format=srt"
    ```

    Best for: video players, caption rendering, accessibility tools.
  </Tab>
</Tabs>

## Filter by speaker or time range

Extract everything one person said:

```bash theme={"dark"}
curl ".../transcript?speaker=Kara+Swisher" \
  -H "X-API-Key: $PARTICLE_API_KEY"
```

Extract a time range:

```bash theme={"dark"}
# Minute 5 to minute 15
curl ".../transcript?start=300&end=900" \
  -H "X-API-Key: $PARTICLE_API_KEY"
```

Combine — exactly what one person said during one segment:

```bash theme={"dark"}
curl ".../transcript?speaker=Scott+Galloway&start=1435&end=2228&format=text"
```

## Word-level transcript

For per-word timing — karaoke-style highlighting, precision editing, word-aligned search:

```bash theme={"dark"}
curl "https://api.particle.pro/v1/podcasts/episodes/78cgekLUjCJBUZbj3s5K8Y/transcript/words?start=0&end=10" \
  -H "X-API-Key: $PARTICLE_API_KEY"
```

```jsonc Response (truncated) theme={"dark"}
{
  "episode_id": "78cgekLUjCJBUZbj3s5K8Y",
  "language": "en",
  "words": [
    { "text": "This", "type": "word", "start_seconds": 0.56, "end_seconds": 0.74, "speaker": "Scott Galloway" },
    { "text": " ",    "type": "spacing", "start_seconds": 0.74, "end_seconds": 0.82, "speaker": "Scott Galloway" },
    { "text": "episode", "type": "word", "start_seconds": 0.82, "end_seconds": 1.12, "speaker": "Scott Galloway" }
    // …
  ],
  "has_more": false
}
```

<Warning>
  Word-level transcripts for long episodes can be very large — a feature-length episode runs to tens of thousands of entries. Pass `start` and `end` to clip a time range, `limit` to bound the page size, and `exclude_spacing=true` if you don't need the inter-word whitespace tokens.
</Warning>

### Query parameters

| Param             | Default            | Description                                                      |
| ----------------- | ------------------ | ---------------------------------------------------------------- |
| `start`           | `0`                | Start time in seconds for time-range clipping.                   |
| `end`             | end of episode     | End time in seconds for time-range clipping.                     |
| `limit`           | unset (return all) | Max words per page (1–5000). Omit to return every matching word. |
| `cursor`          | —                  | Opaque cursor from a previous `cursor` response field.           |
| `exclude_spacing` | `false`            | Drop `type:"spacing"` tokens. See below.                         |

### Spacing tokens

Roughly half of the entries in a typical word transcript have `type:"spacing"` and `text:" "` — these represent the silence *between* spoken words, with their own `start_seconds`/`end_seconds`. They're useful when timing matters: caption/subtitle UIs that need precise pause durations, karaoke-style word highlighting against playback, or reconstructing inter-word silences for audio alignment. NLP, search, and LLM consumers should pass `exclude_spacing=true` to skip them — it roughly halves the payload.

### Pagination

When you pass `limit`, the response includes a `cursor` and `has_more: true` until the last page:

```bash theme={"dark"}
# First page
curl ".../transcript/words?limit=1000&exclude_spacing=true" \
  -H "X-API-Key: $PARTICLE_API_KEY"

# Next page — paste the cursor from the prior response
curl ".../transcript/words?limit=1000&exclude_spacing=true&cursor=r.AbCdEf" \
  -H "X-API-Key: $PARTICLE_API_KEY"
```

The `speaker` field is the identified speaker name (e.g. `Scott Galloway`). When a speaker hasn't been resolved to a name, the raw STT label (`speaker_0`, `speaker_1`, …) is returned instead.

## Transcript mentions

The most useful transcript view when you care about a specific person, company, or topic. Returns the dialogue lines around every mention of an entity in one episode, with `is_mention: true` on the lines that actually contain the mention and surrounding lines for context.

<CodeGroup>
  ```bash curl theme={"dark"}
  curl "https://api.particle.pro/v1/podcasts/episodes/78cgekLUjCJBUZbj3s5K8Y/transcript/mentions?entity_id=sam-altman" \
    -H "X-API-Key: $PARTICLE_API_KEY"
  ```
</CodeGroup>

```jsonc Response (truncated) theme={"dark"}
{
  "episode_id": "78cgekLUjCJBUZbj3s5K8Y",
  "entities": [
    {
      "entity": {
        "id": "5MBAHcKUujL2dzPXrgfQ8E",
        "slug": "sam-altman",
        "name": "Sam Altman"
      },
      "total_mention_count": 5,
      "mention_variants": ["Sam Altman"],
      "mentions": [
        {
          "lines": [
            { "number": 363, "speaker": "Kara Swisher", "text": "Uh, let's go on a quick break.", "is_mention": false, "start_seconds": 1232.53, "end_seconds": 1233.69 },
            { "number": 364, "speaker": "Kara Swisher", "text": "When we come back, Elon Musk and Sam Altman head to court.", "is_mention": true, "start_seconds": 1233.79, "end_seconds": 1236.51 },
            { "number": 365, "speaker": "Kara Swisher", "text": "Big story, actually.", "is_mention": false, "start_seconds": 1236.65, "end_seconds": 1238.09 }
          ],
          "start_seconds": 1231.47,
          "end_seconds": 1246.56
        }
        // …
      ]
    }
  ],
  "has_more": true,
  "cursor": "r.AQAAABk"
}
```

Use `start_seconds` / `end_seconds` to deep-link into the audio, or feed the line text into an LLM with full speaker context.

### Chunking semantics

The endpoint groups transcript lines into context **windows**:

* `context_lines` (default `2`, max `20`) is the radius of each window. A mention on line `i` produces the closed range `[i - context_lines, i + context_lines]`, clamped at the transcript boundaries — so a single mention yields up to `2 * context_lines + 1` lines.
* Adjacent or overlapping windows **merge** into a single window. Two mentions within `context_lines` of each other produce one entry with multiple `is_mention: true` lines, not two entries.
* `total_mention_count` is the unfiltered count of dialogue lines containing at least one mention of the entity in the episode. It is independent of pagination, and equals the sum of `is_mention=true` flags across the un-paginated `mentions[]`.
* Mention matching is a case-sensitive substring match against `mention_variants` (the entity's canonical name plus any annotated aliases).

### Pagination

| Caller shape         | Pagination axis        | Cursor refers to                    |
| -------------------- | ---------------------- | ----------------------------------- |
| `entity_id` provided | `mentions[]` (windows) | offset into windows for that entity |
| `entity_id` omitted  | `entities[]`           | offset into entity list             |

When `entity_id` is set, exactly one entity is returned and its `mentions[]` is paged. When `entity_id` is omitted, each entity in the page returns **all** of its mentions; deep-paging through a single entity's mentions requires re-issuing with that `entity_id`.

`limit` defaults to `25` and is capped at `100`. Pass the `cursor` from a previous response to fetch the next page; `has_more` indicates whether more results exist.

```bash theme={"dark"}
curl "https://api.particle.pro/v1/podcasts/episodes/78cgekLUjCJBUZbj3s5K8Y/transcript/mentions?entity_id=sam-altman&limit=25&cursor=r.AQAAABk" \
  -H "X-API-Key: $PARTICLE_API_KEY"
```

## Segment and clip transcripts

Segments and clips have their own transcript endpoints scoped to that time range:

```bash theme={"dark"}
# Segment transcript
curl "https://api.particle.pro/v1/podcasts/segments/{segment_id}/transcript" \
  -H "X-API-Key: $PARTICLE_API_KEY"

# Clip transcript with SRT export
curl "https://api.particle.pro/v1/podcasts/clips/{clip_id}/transcript?format=srt" \
  -H "X-API-Key: $PARTICLE_API_KEY"
```

Both accept the `format` query parameter (`dialogue`, `text`, or `srt`).

## Related

* [Episodes](/podcasts/episodes) — discovery and sub-resources
* [Segments & clips](/podcasts/segments-and-clips) — get a clip ID, then its transcript
* [Knowledge graph → entities](/knowledge-graph/entities) — pick the entity to mention-search
