---
title: "Put Audio Provider Transcript"
method: PUT
path: "/v2/audios/{audio_id}/transcript"
tags: ["Audio Emotion API"]
---

# Put Audio Provider Transcript

`PUT /v2/audios/{audio_id}/transcript`

## Request

- Base URL: `https://api.imentiv.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.imentiv.ai/v2/audios/{audio_id}/transcript`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer
  - OAuth 2
    - Authorization code: `https://api.imentiv.ai/oauth/authorize`
    - Token URL: `https://api.imentiv.ai/oauth/token` scopes: `media.write`

Attach a transcript produced elsewhere (for example by a meeting provider) to an audio.

The transcript is stored beside the audio's own transcript and does not replace it: the
analysis, speakers and every other result keep using the audio's own transcript, and the
attached one is read back with `GET /v2/audios/{audio_id}/transcript?transcript=provider`.
Speaker display names sent in `speakers` are stored with the attached transcript only; they
do not rename speakers on the audio.

Only one transcript can be attached per audio. Sending again replaces it, whatever its
`source`. Sending the same content again changes nothing and returns the original
`attached_at`, so a request can be retried safely. `replaced` is true only when this request
replaced a different transcript that was already attached.

`start_ms` and `end_ms` are on the audio's own timeline; no offset is applied. Segments are
stored and returned in `start_ms` order. At least one segment is required.

The request body is limited to 1 MiB, the transcript to 10,000 segments, and the stored
content (segments and speaker names) to 640 KiB; over any limit the response is 413 and
nothing is stored. The audio's owner and administrators can attach a transcript. No charge is
applied.

## Path parameters

- `audio_id` string, required: The unique ID of the audio.

## Request body

- ProviderTranscriptRequest: Body of ``PUT /v2/{videos|audios}/{id}/transcript``.
  - `source` 'tldv' | 'zoom' | 'meet' | 'other', required: Where the transcript came from. Use `other` for any other source.
  - `segments` ProviderTranscriptSegment[], required: The whole transcript. Stored and returned in start_ms order; turns with the same start keep the order sent.
    - `speaker` string, required: The speaker's label as the source named it, 1-120 characters after surrounding spaces are removed.
    - `start_ms` integer, required: When the turn starts, in milliseconds on the media's own timeline. No offset is applied: shift the source's clock before sending.
    - `end_ms` integer, required: When the turn ends, in milliseconds. Not before start_ms.
    - `text` string, required: What was said, 1-20000 characters after surrounding spaces are removed.
  - `speakers` object, nullable: Optional display names, keyed by a speaker label used in segments. Each name is 1-60 characters after surrounding spaces are removed.

## Response `200`

Successful Response

- ProviderTranscriptPutResponse: The attached transcript's summary.
  - `media_id` string, required
  - `source` 'tldv' | 'zoom' | 'meet' | 'other', required
  - `segment_count` integer, required
  - `speakers` object, required
  - `attached_at` string, required: When the transcript was first attached in its current form (ISO 8601, UTC).
  - `replaced` boolean, required: True when this request replaced a different provider transcript that was already attached; false for a first attach and for a repeat of identical content.

## Other responses

- `401`: Missing, malformed or rejected credentials — no `X-API-Key` / `Authorization: Bearer <jwt>`, an expired token, or a caller that lacks the role the route requires. Note that this API answers *authorization* failures with 401 as well as 403 (see the 403 entry where a route declares both).
- `404`: No such resource, or it is not visible to this caller. Ownership failures are reported as 404 rather than 403 so the API does not confirm the existence of another account's records.
- `413`: `provider_transcript_too_large`: the request body, the number of segments or the stored transcript content is over the limit. Nothing was stored.
- `422`: Request validation failed. The app flattens FastAPI's validation error list into a single `detail` string, so the body is `{"detail": "'field' <message>"}` and NOT FastAPI's default `HTTPValidationError`. Declaring this overrides the auto-generated 422 — see the module docstring.

## Changes

- **2026-10-07** `45bdd041d683`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/imentiv/apis/welcome-to-imentiv-ai/changes/v2/audios/:audio_id/transcript/put.md)

---

[API](https://skmtc.dev/imentiv/apis/welcome-to-imentiv-ai.md) - [All operations](https://skmtc.dev/imentiv/apis/welcome-to-imentiv-ai/llms.txt) - [OpenAPI document](https://skmtc.dev/imentiv/apis/welcome-to-imentiv-ai/revisions/bc15cec7e794?raw)
