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

> ## Agent Instructions
> Arcmira has three API capabilities: Search (entities, mentions, appearances, commercial intelligence), Monitors (trackers plus alert delivery), and Transcripts (read, generate, correct). Community Review is the cross-surface correction layer.
> Discover pages at https://arcmira.com/docs/llms.txt, then fetch the matching page's .md export. Each capability has a self-contained '<capability> for coding agents' page; prefer it.
> Auth: Authorization: Bearer arc_sk_... or x-api-key: arc_sk_... (x-api-key wins if both are sent). Never put keys in browser code. Check GET /v1/me for tier, scopes, and remaining rows before metered pulls.
> Search: resolve names with GET /v1/entities/lookup and pin ent_* IDs before pulling metered rows. Only person entities have appearances. Mention and recommendation rows carry canonical numeric timestamps in start_seconds/end_seconds (integer seconds; 0 means full episode); the MM:SS string fields are deprecated. Commercial routes need Pro+ tier AND the recommendations:read scope and bill 10 rows per row.
> Monitors: a tracker watches one entity; a monitor groups trackers with shared delivery (email, Slack, HMAC-signed webhooks). Create trackers with POST /v1/trackers, then attach by id: POST /v1/monitors/{id}/trackers { trackerIds: [...] }. Each fired alert occurrence debits 100 rows. Poll GET /v1/monitors/{id}/alerts?n= for recent deliveries. Send Idempotency-Key on every POST/PATCH.
> Transcripts: switch on the access field (unlocked, locked, premium_pending, not_transcribed, unauthenticated). Honor Retry-After when polling POST /v1/transcriptions jobs. Corrections (POST /v1/videos/{video_id}/corrections; kinds line_edit, speaker_reassign, speaker_identify, add_person, entity_tag, segment_rewrite) cost 0 rows; anchored kinds need revision + anchor.contentHash (djb2 base-36); handle 409 (re-anchor) and 412 (expectedSeq). segment_rewrite replaces an inclusive segment range with new segments (empty replacements array deletes; timestamps repaired server-side).
> Community Review is free (0 rows) and surface-typed: POST /v1/feedback with a type matching the surface you called, the reproducing query, and corrections targeting public IDs (ent_*, men_*, com_*). Nothing auto-applies. Do not send untyped notes.
> Errors: switch on error.code, follow doc_url, quote X-Request-Id to support. Honor Retry-After on 429. Retries of POST/PATCH must reuse the same Idempotency-Key; replays return Idempotency-Replayed: true.
> Teams Admin API: GET /v1/team/members, /v1/team/spend, /v1/team/usage-events (cursor-paginated, 90-day bound) are read-only and require a team-scoped API key created by a team admin; personal keys get 403 team_key_required.

# Transcripts

> Read full annotated video transcripts, generate them on demand, and correct them through community review.

<div className="callout-box not-prose">
  <p className="callout-title">Just want working code?</p>

  <p className="callout-body">
    Stop reading and copy the [Transcripts coding agent reference](/docs/transcripts-for-coding-agents) into your agent. It is self-contained, including the polling and correction contracts.
  </p>
</div>

Arcmira serves **premium transcripts**: diarized, speaker-identified, entity-annotated, community-correctable, and it can generate one on demand for any public YouTube video up to 12 hours. Every segment is matched against the entity graph, so people, organizations, products, and topics are annotated inline with character-level spans.

```text theme={null}
GET  /v1/transcripts/{video_id}          read (teaser until unlocked)
POST /v1/transcriptions                  submit a video for transcription
GET  /v1/transcriptions/{id}             poll status (Retry-After)
POST /v1/videos/{video_id}/corrections   submit corrections (free)
```

## Key capabilities

| Capability            | What it does                                                        |
| --------------------- | ------------------------------------------------------------------- |
| Premium transcripts   | Diarized segments with seconds-level timing and speaker attribution |
| Entity annotations    | Character-span links from transcript text into the entity graph     |
| On-demand generation  | Submit any public YouTube video; agent-friendly polling             |
| Permanent unlocks     | Pay once per video per account; every later read is free            |
| Community corrections | Six correction kinds, from line edits to structural rewrites, free  |

## Pricing

Transcript access is priced in **rows and 15-minute blocks**, from the same row pool as the rest of the API:

* **75 rows per 15-minute block** of video, rounded up, minimum one block. A 62-minute podcast is 5 blocks = 375 rows; a 9-minute clip is 75 rows.
* Same price whether a premium transcript already exists or Arcmira generates it fresh.
* Unlocks are **permanent and per-account**. Re-reads are free. Unlock before the premium transcript exists and the later generation costs nothing extra.
* If a transcription job fails permanently, rows are **refunded automatically** and the unlock is revoked (when that submission charged the rows; the status reads `refunded`).
* Corrections are always free (0 rows).

Every transcript response includes the exact quote in `meta.quote` (`{ "quarters": 5, "rows": 375 }`) whenever the video duration is known.

## Quickstart

<Steps>
  <Step title="Read (and see where you stand)">
    ```bash theme={null}
    curl 'https://api.arcmira.com/v1/transcripts/dQw4w9WgXcQ' \
      -H "Authorization: Bearer $ARCMIRA_API_KEY"
    ```

    Switch on the `access` field; the table below tells you the next action for each state.
  </Step>

  <Step title="Unlock or generate">
    A premium transcript exists (`locked`): purchase in the same request with `?unlock=true`; the quoted rows are debited and the full transcript comes back in one round trip. No premium transcript yet (`premium_pending` / `not_transcribed`): submit it.

    ```bash theme={null}
    curl -X POST 'https://api.arcmira.com/v1/transcriptions' \
      -H "Authorization: Bearer $ARCMIRA_API_KEY" \
      -H "Idempotency-Key: $(uuidgen)" \
      -H "Content-Type: application/json" \
      -d '{ "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }'
    ```

    Rows are debited up front and the permanent unlock is granted at submit time.
  </Step>

  <Step title="Poll politely">
    While in flight, `GET /v1/transcriptions/{id}` carries a `Retry-After` header plus `etaSeconds` and `nextPollSeconds`. Sleep on the header and re-poll; terminal statuses drop it. On `complete`, the transcript GET just works: you were unlocked at submission.
  </Step>
</Steps>

## Choosing well

**The `access` state machine.** Every read tells you exactly where you stand; each state has one right next action:

| `access`          | Meaning                                                                   | Next action                                                  |
| ----------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------ |
| `unlocked`        | Full premium transcript in the payload                                    | Use it; re-reads are free                                    |
| `locked`          | Premium transcript exists, you haven't bought it                          | `?unlock=true` (quote in `meta.quote`)                       |
| `premium_pending` | Preliminary analysis only: entity-type **counts**, no text, no timestamps | `POST /v1/transcriptions` (unlock has nothing to unlock yet) |
| `not_transcribed` | Not in the index                                                          | `POST /v1/transcriptions`                                    |
| `unauthenticated` | Teaser only (web sessions; the API always requires a key)                 | Authenticate                                                 |

**Buy vs generate.** `?unlock=true` purchases access to an existing premium transcript. `POST /v1/transcriptions` purchases generation (and short-circuits to `complete` if a premium transcript already exists, so it is always safe to call; you are never double-charged, and `quote.rows` in the response shows what was actually debited).

**Cost control.** Duration drives price. Quote first (`meta.quote` on any read costs nothing), check `/v1/me` → `usage.rows_remaining`, then unlock. `402 quota_exceeded` responses include the quote.

## Response shape

```json theme={null}
{
  "video": { "videoId": "dQw4w9WgXcQ", "title": "…", "channelName": "…", "durationSeconds": 3720 },
  "access": "unlocked",
  "segments": [
    { "index": 0, "start": 0.4, "end": 6.1, "text": "Welcome back to the show…", "speaker": 0 }
  ],
  "speakers": [
    { "id": 0, "label": "Speaker 0", "entity": { "id": 147403, "name": "Emad Mostaque", "slug": "emad-mostaque" } }
  ],
  "annotations": [
    { "segmentIndex": 12, "charStart": 34, "charEnd": 40, "entityId": 120034, "entityType": "organization", "name": "OpenAI", "slug": "openai" }
  ],
  "meta": { "diarized": true, "locked": false, "revision": "rwmksmk", "quote": { "quarters": 5, "rows": 375 } }
}
```

* **`segments`**: transcript lines with `start`/`end` in seconds and a diarization `speaker` id.
* **`speakers`**: the diarization map; entries gain an `entity` once identified as a person.
* **`annotations`**: entity mentions as character spans inside segment text.
* **`meta.revision`**: an opaque id for the served transcript plus its approved-correction state. **Save it**: corrections echo it back, and a changed revision means the transcript changed underneath you.
* When unlocked, your own pending corrections ride back too (`edits[]`, `speakerIdentifications[]`, `speakerEdits[]`, `entityTags[]`).

## Corrections

Transcripts are community-correctable, free, and **optimistic for you, pending review for everyone else**: your pending corrections appear on your own transcript reads immediately; once a reviewer approves them they apply for all callers and bump `meta.revision`. Five kinds mirror the arcmira.com `/watch` editor; the sixth, `segment_rewrite`, is the API-first structural primitive.

| `kind`             | What it does                                                                                         |
| ------------------ | ---------------------------------------------------------------------------------------------------- |
| `line_edit`        | Fix the text of one segment.                                                                         |
| `speaker_reassign` | Move lines (or part of a line: a sub-line split) to another speaker, a new speaker, or a voice role. |
| `speaker_identify` | Link a diarization speaker to a person entity. Creates a community-flagged appearance immediately.   |
| `add_person`       | Propose a person not in the index yet and link the speaker in one action.                            |
| `entity_tag`       | Tag an entity mention the pipeline missed, as a character span.                                      |

```bash theme={null}
curl -X POST 'https://api.arcmira.com/v1/videos/dQw4w9WgXcQ/corrections' \
  -H "Authorization: Bearer $ARCMIRA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "kind": "line_edit",
    "revision": "rwmksmk",
    "anchor": { "segmentIndex": 12, "contentHash": "1a2b3c" },
    "payload": {
      "segmentIndex": 12,
      "originalText": "Anthropics new cloud 4.5",
      "correctedText": "Anthropic'\''s new Claude 4.5"
    }
  }'
```

Anchored kinds (`line_edit`, `speaker_reassign`, `entity_tag`, `segment_rewrite`) prove they were made against the transcript you actually saw: echo `meta.revision`, and send `anchor.contentHash`, a djb2 hash (base-36) of the covered segment text. A `409` means the transcript changed underneath you (re-anchor); a `412` with `expectedSeq` means your sequence counter is behind (rebase and resend). Full payload schemas for all six kinds, the hash function, and the queue-client error contract live in the [coding agent reference](/docs/transcripts-for-coding-agents#corrections).

Withdraw anything you regret while it is still pending; each submission returns the row `id` for the matching `DELETE`.

<Note>
  **Structural rewrites**: `segment_rewrite` replaces any run of segments with new ones, merges, splits, or deletes them outright, and repairs the timestamps automatically. Full payload in the [coding agent reference](/docs/transcripts-for-coding-agents#corrections).
</Note>

## Community Review

Corrections **are** Community Review on the transcript surface: same pending-review model, same 0-row pricing, same attribution and reputation. For anything that is not a transcript-content fix (a wrong video, a stale channel, a search miss that led you here), use the matching type on [`POST /v1/feedback`](/docs/feedback).

## Next

* [Transcripts for coding agents](/docs/transcripts-for-coding-agents): full endpoint tables, all six correction payloads, the outbox/queue contract.
* [Search](/docs/search): the entity graph these annotations link into.
* [Community Review](/docs/feedback): the cross-surface correction catalog.
* [API reference](/docs/api-reference/transcripts/get-a-video-transcript): interactive playground.
