# Stream one live conversation's transcript (/docs/api/voice-agents/live-conversations/streamLiveTranscript)

> For the complete documentation index, see [llms.txt](https://docs.tandemcx.ai/llms.txt). Any page on this site can be fetched as Markdown by appending `.md` to its URL.

`GET /v1/agent-media/live-conversations/transcript-stream`

Stream one live conversation's transcript

A [server-sent events](https://developer.mozilla.org/docs/Web/API/Server-sent_events) stream of what is being said on one conversation that is live right now, pushed turn by turn. Works for either `channel`: a `voice` call streams as it is spoken, a `chat` as messages are sent. The connection stays open until you close it or the conversation is over.

The first `seed` event carries everything said so far, so a client that only opens the stream needs no separate read. Each later `append` event carries only the turns added since the previous event — append them, do not replace what you have. A further `seed` may arrive in place of an `append`, and REPLACES what you have: a long chat's stored history is trimmed from the front, so the conversation can lose its head as well as gain a tail. A final `ended` event says the conversation is over; nothing follows it and the connection then closes. A chat ends when the agent finishes it, when it reaches its message limit, or when it passes 24 hours without a message and so can no longer be continued. Going idle is NOT ending — an idle chat's stream simply stays open and quiet, because the visitor may still reply. Comment lines (`: keep-alive`) arrive periodically and carry no data; ignore them.

A `coaching` event carries a supervisor's coaching note on the conversation: `id`, `at`, `text`, `author`, `about` when the note is about an earlier message (see `CoachingNoteAbout`), and `appliedTurn` once the agent has taken it into a turn. Every note already written arrives right after the `seed`, and a note arrives again when `appliedTurn` is set; keep the latest per `id`.

A `held_reply` event carries a chat reply the agent has written but the visitor has not yet seen, held for review because the conversation carries an alert: `id`, `text`, `deadline`, and `status`, which is `pending` until a supervisor sends it (`approved`), sends an edit (`edited`, with `editedText`), or the deadline passes and it sends itself as written (`expired`). A pending reply arrives right after the `seed`, and again each time its `status` or `deadline` changes; keep the latest. Ignore any event name you do not recognise: more may be added.

Once a supervisor has taken a call over, the transcript goes on with what the caller and the supervisor say, transcribed apart. A `phase` event says so, once: `phase` is `supervised`, with `since` and `by` (`userId` and `name`, which is null when it could not be resolved). A `supervised_seed` event then carries every line said since, and each `supervised_append` the lines added after it. A line carries `id`, `speaker` (`caller` or `supervisor`), `text`, `at`, and, on a supervisor's line, their `userId` and `name`. These lines are never `turns`: the agent has left the call, and they come after its last one. The stream ends when the supervisor's call does. A stream opened after the take-over still starts with the agent's part as its `seed`.

A `presence` event, sent only when `presence` is `tile` or `view`, says what this supervisor may do on the conversation and who else has it: `you` is `monitor` when they are the one monitoring it, and `viewer` otherwise, in which case they may read it but not act on it. That includes when nobody monitors it, until they claim it. `presence` carries the `monitor`, if any, and the `viewers`, as the conversation's `presence` does on the live conversations collection. It is sent when the stream opens and again whenever either changes. The transcript after a take-over is being rolled out, so an organization may not see it yet.

A tool call is a turn of its own with `role` `tool`, carrying a `tool` object (see `ToolCall`). `truncated` becomes true once the conversation has passed the retained-transcript size limit, after which no further turns are added.

The conversation id is a query parameter rather than a path segment, and this endpoint is read with `fetch` and a streaming response body rather than `EventSource`, which cannot send an `Authorization` header.

Each event's `data` is JSON in which `<` and `>` are written as the escapes `\u003c` and `\u003e`. `JSON.parse` restores both characters, so parse the payload rather than matching against its raw text.

## Request

**Base URL:** `https://api.tandemcx.ai`

**Authentication:** `Authorization: Bearer <token>` — A Tandem bearer token. Requests are scoped to the organization the token belongs to; no organization header is required.

### Query parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `conversationId` | string | Yes | The `conversationId` of a conversation that is live right now, as returned by the live conversations collection. |
| `presence` | enum: `tile` \| `view` \| `none` | No | `tile` when this stream backs a transcript the supervisor has open: it monitors the conversation if nobody else does, and views it otherwise, for as long as the stream is open. `view` views it and never claims it, for a viewer reconnecting. Omitted or `none`, the stream reads the transcript and claims nothing. |

## Responses

### 200 — The event stream. A `seed` and each `append` event's `data` carries `turns` and `truncated`; `ended` carries an empty object.

Type: string

### 400 — The `conversationId` is missing or malformed.

No response body.

### 401 — Missing, malformed, or expired bearer token.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | string | No | A stable machine-readable code. |
| `message` | string | No | A human-readable explanation, safe to show to an end user. Present on errors an operator can act on; browser clients display this field in preference to a generic fallback. |
| `limit` | integer | No | Present on some errors (e.g. `prompt_too_long`) that reject a value against a fixed bound: the bound itself. |
| `length` | integer | No | Present on some errors (e.g. `prompt_too_long`) that reject a value against a fixed bound: the measured size of the rejected value. |
| `reason` | string | No | Present on some errors (e.g. `invalid_avatar_image`) that have more than one cause: which one applied. |

### 403 — The token verified but carries no usable organization — either no organization at all, or one whose id is malformed — so there is nothing to scope the read to. Re-authenticating will not resolve it.

No response body.

### 404 — No conversation with this id is live for the organization — because it has ended, because it never existed, or because it belongs to another organization, which is reported the same way rather than as a refusal. There is no stored transcript behind this endpoint; for a finished call, use the call transcript endpoint instead.

No response body.
