# How a session works

A live session is one stream of audio and everything transcribed from it.

## Lifecycle

1. **Create** the session: [`POST /v2/live`](/api-reference/v2/live/init/) with its options. It answers the session
   `id` and a WebSocket `url`, valid 60 seconds.
2. **Connect** to the `url`. With `messages_config.receive_lifecycle_events`, a
   [`start_recording`](/api-reference/v2/live/message/start-recording/) message says the session is ready.
3. **Stream** the audio, as binary frames or [`audio_chunk`](/api-reference/v2/live/websocket/#send) messages.
   Transcripts arrive as the audio is processed.
4. **Stop** with `{"type": "stop_recording"}`. The server transcribes what is left, sends `end_recording`, the
   post-processing results ([`post_transcript`](/api-reference/v2/live/message/post-transcript/),
   [`post_final_transcript`](/api-reference/v2/live/message/post-final-transcript/)), `end_session`, then closes the
   connection with code `1000`.

A session also stops after 60 seconds without audio, and when it reaches its maximum duration
([Limits](/limits/concurrency/)).

## Utterances

The audio is cut into **utterances** at pauses ([Endpointing](/live/endpointing/)). Each utterance has an `id`,
`<channel>_<index>` (`00_00000003`), stable for the whole session. While it is spoken you receive **partial**
transcripts (`is_final: false`, with `receive_partial_transcripts`), each replacing the previous one; when it ends,
one **final** transcript (`is_final: true`).

```json
{
  "type": "transcript",
  "session_id": "0199d7a2-5c3e-7b41-9f0a-3c2d1e4f5a6b",
  "created_at": "2026-10-12T09:04:19.000Z",
  "data": {
    "id": "00_00000003",
    "is_final": true,
    "utterance": {
      "text": "I'd like to change my delivery address.",
      "start": 12.48,
      "end": 14.9,
      "language": "en",
      "confidence": 0.94,
      "channel": 0,
      "words": [{ "word": "I'd", "start": 12.48, "end": 12.62, "confidence": 0.97 }]
    }
  }
}
```

The features you turn on add their own messages right after each final (translation, entities, redacted data,
sentiment), named by the same utterance `id`.

## Choosing your messages

`messages_config` in the init body selects what comes on the WebSocket:

| option | messages | default |
|---|---|---|
| `receive_partial_transcripts` | `transcript` with `is_final: false` | `false` |
| `receive_final_transcripts` | `transcript` with `is_final: true` | `true` |
| `receive_speech_events` | `speech_start`, `speech_end` | `true` |
| `receive_realtime_processing_events` | `translation`, `named_entity_recognition`, `sentiment_analysis` | `true` |
| `receive_post_processing_events` | `post_transcript`, `post_final_transcript` | `true` |
| `receive_acknowledgments` | `audio_chunk`, `stop_recording` acknowledgments | `true` |
| `receive_lifecycle_events` | `start_recording`, `end_recording`, `end_session` | `false` |
| `receive_errors` | `error` | `true` |

`pii` and `end_of_turn` messages come whenever their feature is on. Every message type is described in the
[API reference](/api-reference/v2/live/websocket/#receive). The same messages can also go to your server
([Callbacks](/live/callbacks/)).

## After the session

[`GET /v2/live/{id}`](/api-reference/v2/live/get/) returns the session's options and, once it is `done`, its
result: every final utterance, the full transcript and the translations. Sessions stay in your history for your
account's retention ([Data retention](/data/retention/)).
