---
title: "Label a passage"
method: POST
path: "/media/{mediaId}/labels"
tags: ["Labels"]
---

# Label a passage

`POST /media/{mediaId}/labels`

## Request

- Base URL: `https://api.speakai.co/v1`
- URL: `https://api.speakai.co/v1/media/{mediaId}/labels`
- Auth: API key in header `x-speakai-key` and API key in header `x-access-token`

Requires the **Labels: Assign** permission (on by default for admins and members). The media must belong to your company and be one you can open. Owners and members with the folder **Access all** permission can open any file; everyone else can open files in folders assigned to them or their groups, and files they own. Any other media returns 404, the same as a media id that does not exist.

#### How to address words

Send the word range and the revision you read it from. Word positions count every word of the transcript in order, starting at 0. Within each sentence, words come from `entities` in order (an entity that holds several words, such as "New York", counts as several), or from the sentence `text` split on whitespace when the sentence has no entities. A token that is only punctuation is not counted. `expectedTranscriptRevision` is the `transcriptRevision` you read the transcript at, from `GET /media/transcript/{mediaId}`, `GET /media/insight/{mediaId}`, or the list endpoints on this page. The server builds the anchor from its own copy of the transcript. If the transcript has been saved since, the request returns 409 "This transcript changed since you opened it. Reload to keep editing." and nothing is written: read the transcript again and recompute the word range.

#### Request rules

- When the same words already carry labels at this revision, the labels you send are added to that passage and the existing passage is returned.
- A transcript holds at most 5,000 labelled passages; past that the request returns 400.

#### Errors

- `400` when a field fails validation, the range runs past the transcript, a label is archived, a group or not in your company, or the passage limit is reached.
- `403` without the permission.
- `404` when the media does not exist or you cannot open it.
- `409` when `expectedTranscriptRevision` is stale.

## Path parameters

- `mediaId` string, required

## Request body

- object
  - `range` object, required: Inclusive range of word positions. Word positions count every word of the transcript in order, starting at 0. Within each sentence, words come from `entities` in order (an entity that holds several words, such as "New York", counts as several), or from the sentence `text` split on whitespace when the sentence has no entities. A token that is only punctuation is not counted.
    - `start` integer, required: Position of the first word. Integer, 0 or more.
    - `end` integer, required: Position of the last word, inclusive. Integer, at least `start`. A range that runs past the last word returns 400 "The selected words are outside this transcript."
  - `labelIds` string[], required: Labels to put on the passage. 1 to 20 ids, no repeats. Each must be an active label (not a group) in your company, or the request returns 400 "Choose active labels from this workspace (groups cannot be applied)."
  - `expectedTranscriptRevision` integer, required: The `transcriptRevision` you read the transcript at. Integer, 0 or more. A stale value returns 409.

## Response `200`

Success

- object
  - `status` 'success': `success` on every 2xx response.
  - `data` object: Labels on one passage of a transcript.
    - `mediaLabelId` string: Id of the labelled passage.
    - `mediaId` string: Id of the media.
    - `labelIds` string[]: Labels on the passage.
    - `anchor` object: Where the passage sits in the transcript. Built by the server from the word range you send.
      - `startWord` integer: Position of the first word.
      - `endWord` integer: Position of the last word, inclusive.
      - `exact` string: The quoted words, joined by single spaces.
      - `prefix` string: Up to 32 characters of transcript text before the quote.
      - `suffix` string: Up to 32 characters of transcript text after the quote.
      - `startInSec` number: Start time of the first word, in seconds.
      - `endInSec` number: End time of the last word, in seconds.
      - `speakerIds` string[]: Speakers of the quoted words.
      - `transcriptRevision` integer: The transcript revision these positions refer to.
    - `status` 'active' | 'shifted' | 'needs_review': `active`: the same words, possibly at new positions after an edit. `shifted`: most of the words survived an edit near the same time, but the text changed. `needs_review`: the words changed too much to follow; `anchor` then holds a suggested passage on the new transcript and `lastResolved` the last position a person confirmed.
    - `lastResolved` object: Present only while `status` is `needs_review`: the last position a person confirmed.
      - `startWord` integer: Position of the first word.
      - `endWord` integer: Position of the last word, inclusive.
      - `exact` string: The quoted words, joined by single spaces.
      - `prefix` string: Up to 32 characters of transcript text before the quote.
      - `suffix` string: Up to 32 characters of transcript text after the quote.
      - `startInSec` number: Start time of the first word, in seconds.
      - `endInSec` number: End time of the last word, in seconds.
      - `speakerIds` string[]: Speakers of the quoted words.
      - `transcriptRevision` integer: The transcript revision these positions refer to.
    - `userId` string: Id of the person who first labelled the passage.
    - `createdAt` string, date-time: When it was created.
    - `updatedAt` string, date-time: When it last changed.

## Other responses

- `400`: Validation, range, label or limit problem
- `403`: You lack the Labels: Assign permission
- `404`: The media does not exist or you cannot open it
- `409`: The transcript changed since you read it

---

[API](https://skmtc.dev/speakai/apis/speak-ai-api.md) · [All operations](https://skmtc.dev/speakai/apis/speak-ai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/speakai/apis/speak-ai-api/revisions/52d777e6d46e?raw)
