> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chariot.in/llms.txt
> Use this file to discover all available pages before exploring further.

# Audio formats

> Audio encodings and sample rates for streaming speech to text, including telephony audio, chunk sizes, and browser capture.

The streaming WebSocket accepts raw mono audio in the encoding and sample rate you declare with the `audio_format` query parameter. The default is `pcm_16000`.

## Supported formats

| `audio_format` | Encoding | Sample rate | Bytes per second |
| - | - | - | - |
| `pcm_8000` | Signed 16-bit little-endian PCM | 8 kHz | 16,000 |
| `pcm_16000` (default) | Signed 16-bit little-endian PCM | 16 kHz | 32,000 |
| `pcm_22050` | Signed 16-bit little-endian PCM | 22.05 kHz | 44,100 |
| `pcm_24000` | Signed 16-bit little-endian PCM | 24 kHz | 48,000 |
| `pcm_32000` | Signed 16-bit little-endian PCM | 32 kHz | 64,000 |
| `pcm_44100` | Signed 16-bit little-endian PCM | 44.1 kHz | 88,200 |
| `pcm_48000` | Signed 16-bit little-endian PCM | 48 kHz | 96,000 |
| `ulaw_8000` | G.711 mu-law, 8 bits per sample | 8 kHz | 8,000 |
| `alaw_8000` | G.711 A-law, 8 bits per sample | 8 kHz | 8,000 |

All formats are **mono**. Send raw samples only: no WAV or other file header, no container, and no compression beyond G.711. Stereo audio must be mixed down to one channel first.

An unsupported `audio_format` is rejected with an `error` event and close code `1008`.

## Declare the rate you send

`audio_format` must match the audio exactly. Audio at a different rate than declared is not rejected: it is transcribed as sped-up or slowed-down speech, which produces wrong text. If transcripts look plausible but wrong, check the sample rate first.

Send audio at the rate it was captured or recorded. You do not need to resample it yourself: Chariot converts every supported rate on the server.

## Telephony

Phone audio is usually 8 kHz G.711. Declare the encoding your provider delivers and send its bytes unchanged:

| Network | Typical encoding | `audio_format` |
| - | - | - |
| India, Europe, most E1 trunks | A-law | `alaw_8000` |
| North America, Japan | mu-law | `ulaw_8000` |
| Provider delivers 16-bit PCM at 8 kHz | Linear PCM | `pcm_8000` |

Check your provider's media settings to confirm which one it sends. Mixing them up produces noisy, unusable transcripts.

Many telephony media streams wrap audio in JSON messages as base64. Decode the base64 and send the raw bytes to Chariot as binary frames.

For a phone call, open one session per call leg you want transcribed. Each session uses one [concurrency slot](/guides/resources/rate-limits) for as long as it is open.

## Chunk size

Any frame size works, and a frame does not have to end on a sample boundary. Frames of **50 to 200 ms** work well for live audio. Smaller frames add per-message overhead, and larger frames delay the first text by up to the frame length.

| `audio_format` | 100 ms frame |
| - | - |
| `pcm_16000` | 3,200 bytes |
| `pcm_8000` | 1,600 bytes |
| `pcm_48000` | 9,600 bytes |
| `ulaw_8000`, `alaw_8000` | 800 bytes |

With a live source, send each frame as soon as you have it. With a recording, the [quickstart](/guides/speech-to-text/quickstart) paces frames at real time to behave like a microphone.

## Silence and pauses

Every second of audio you send is billed, including silence. Text for your most recent speech arrives only after more audio follows it, and `high_accuracy` holds back more of it than `balanced`. For live conversations, keep streaming through short pauses, silence included, so that text arrives during the pause.

When there is no audio at all, for example while a microphone is muted, stop sending frames and send `{"type": "keepalive"}` messages instead. They keep the session open and are not billed, but they do not bring out held-back text. That text arrives when audio resumes or when you send `input.done`. See [Keeping a session open](/guides/speech-to-text/websocket#keeping-a-session-open).

## Browser microphones

Browsers capture audio as 32-bit floating-point samples, usually at 48 kHz (read `AudioContext.sampleRate` to be sure). Convert each block to 16-bit integers and declare the matching format, for example `pcm_48000`:

```javascript JavaScript theme={null}
// Convert Web Audio float samples (-1 to 1) to 16-bit little-endian PCM.
function floatTo16BitPCM(float32) {
  const out = new DataView(new ArrayBuffer(float32.length * 2));
  for (let i = 0; i < float32.length; i++) {
    const s = Math.max(-1, Math.min(1, float32[i]));
    out.setInt16(i * 2, s < 0 ? s * 0x8000 : s * 0x7fff, true);
  }
  return out.buffer;
}

// Connect with audio_format=pcm_ + audioContext.sampleRate, then send:
// socket.send(floatTo16BitPCM(samples));
```

> [!WARNING]
>
> Do not put your API key in browser code. Relay the audio through your own server, which connects to Chariot with the `chariotai-api-key` header.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.