# Audio Stream Fields

When Cloud Voice streams live call audio to a third-party platform, it sends the conversation over a WebSocket connection as a sequence of JSON messages. Each message carries one fragment of audio together with metadata that identifies the call and the party who is speaking. Integrations that consume this stream include live transcription, real-time analytics, and voice recording services. The voice payload is captured as 16-bit little-endian PCM (Pulse-Code Modulation), Base64-encoded, and placed in the message. This page describes each field you will find in those messages.

:::note
To turn a message back into playable audio, Base64-decode the `audio` value, then read the resulting bytes as signed 16-bit samples in little-endian order (least significant byte first). Reading the samples in the wrong byte order produces distorted audio, so match this format on the receiving side.
:::

## Message fields

| Field | Description |
| --- | --- |
| `channelid` | Channel ID of an individual party in the call. |
| `callid` | Unique identifier for the call. |
| `callflow` | The call scenario. Empty when the call does not match any of the scenarios listed below. |
| `number` | Caller ID associated with the party. |
| `status` | Current state of the audio stream for this party. |
| `audio` | Base64-encoded PCM payload carrying the party's voice data. |

### `callflow` values

When the call matches a recognized scenario, `callflow` is set to one of the following:

- `ivr`, the call was routed through an IVR (Interactive Voice Response), the automated menu that plays a greeting and collects key presses.
- `queue`, the call passed through a call queue that holds callers until an agent is free.
- `ringgroup`, the call rang a ring group, a set of extensions that ring together.
- `cfd`, the call was handled by a Call Flow Designer flow (a custom, drag-and-drop routing flow).
- `conference`, the call is part of a conference room with multiple participants.
- `multicast_paging`, the call is a multicast paging announcement broadcast to a group of endpoints.

### `status` values

- `process`, audio is still being transmitted for this party.
- `end`, the stream for this party has finished. The `audio` field is empty in this message. Treat the `end` message as your signal that no more audio will arrive for that party, so you can close or finalize your handling of that stream.

:::tip
To pull additional details about a stream, take the `callid` from the message and query the matching call record through the Cloud Voice call API.
:::

## Message examples

How audio is transmitted depends on how many parties are on the call.

### One-on-one calls

For a call between two parties, Cloud Voice opens a single WebSocket connection to the third-party platform and interleaves audio from both parties over it. The two parties are distinguished by their `channelid`, which acts as a logical channel within the shared connection.

While the call is in progress, each party's audio arrives on its own channel:

Channel 1:

```json
{
  "callid": "1755940023.7",
  "callflow": "",
  "audio": "UkSDFj82nJKLm90qweRTyVxZaBcDeFgHiJkLmNoPqRsTuVwXyZ1234567890ABCD...",
  "number": "1009",
  "status": "process",
  "channelid": "PJSIP/1009-XXXXX005"
}
```

Channel 2:

```json
{
  "callid": "1755940023.7",
  "callflow": "",
  "audio": "WHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA...",
  "number": "1010",
  "status": "process",
  "channelid": "PJSIP/1010-XXXXX006"
}
```

When the call ends, a final message is sent on each channel with an empty `audio` field and `status` set to `end`:

Channel 1:

```json
{
  "callid": "1755940023.7",
  "callflow": "",
  "audio": "",
  "number": "1009",
  "status": "end",
  "channelid": "PJSIP/1009-XXXXX005"
}
```

Channel 2:

```json
{
  "callid": "1755940023.7",
  "callflow": "",
  "audio": "",
  "number": "1010",
  "status": "end",
  "channelid": "PJSIP/1010-XXXXX006"
}
```

### Multi-party calls

For a call with more than two parties, Cloud Voice opens a dedicated WebSocket connection for each party and sends that party's audio on its own connection. This means the number of open connections grows with the number of parties, so a large conference results in many simultaneous connections to the third-party platform.

:::note
If a call grows from two parties into a multi-party call, Cloud Voice closes the shared connection and opens a separate WebSocket for each party. The original parties keep their existing `channelid` and `callid` values, so you can correlate the new per-party streams with the earlier interleaved audio.
:::

The example below shows the messages for a three-party conference, with each party's audio streamed over its own WebSocket connection.

While the call is in progress:

Channel 1:

```json
{
  "callid": "1769052671.54",
  "callflow": "conference",
  "audio": "Lm90qweRTyVxZaBcDeFgHi5ccll...",
  "number": "1000",
  "status": "process",
  "channelid": "PJSIP/1000-XXXX0020"
}
```

Channel 2:

```json
{
  "callid": "1769052671.54",
  "callflow": "conference",
  "audio": "HiJkLmNoPqRsTuVwXyZ1234567890ABCD...",
  "number": "1001",
  "status": "process",
  "channelid": "PJSIP/1001-XXXX0021"
}
```

Channel 3:

```json
{
  "callid": "1769052671.54",
  "callflow": "conference",
  "audio": "WHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5c...",
  "number": "2131005",
  "status": "process",
  "channelid": "PJSIP/2131005-XXXX0022"
}
```

When the call ends, each connection sends a final message with an empty `audio` field and `status` set to `end`:

Channel 1:

```json
{
  "callid": "1769052671.54",
  "callflow": "conference",
  "audio": "",
  "number": "1000",
  "status": "end",
  "channelid": "PJSIP/1000-XXXX0020"
}
```

Channel 2:

```json
{
  "callid": "1769052671.54",
  "callflow": "conference",
  "audio": "",
  "number": "1001",
  "status": "end",
  "channelid": "PJSIP/1001-XXXX0021"
}
```

Channel 3:

```json
{
  "callid": "1769052671.54",
  "callflow": "conference",
  "audio": "",
  "number": "2131005",
  "status": "end",
  "channelid": "PJSIP/2131005-XXXX0022"
}
```
