---
title: "Open a two-person live interpretation session"
method: GET
path: "/v1/audio/interpretations/stream"
tags: ["Interpretation"]
---

# Open a two-person live interpretation session

`GET /v1/audio/interpretations/stream`

## Request

- Base URL: `https://api.pyai.com`
- URL: `https://api.pyai.com/v1/audio/interpretations/stream`
- Auth: one of:
  - HTTP bearer
  - API key in header `x-api-key`

Connect over WebSocket with a live key holding `interpret:session`. Server clients use Bearer authentication; browsers use an origin-locked token from the session mint and offer `pyai.v1`, then `pyai-key.<token>` as subprotocols. Credentials are never accepted in the URL.

After `hello`, send `session.start` with `external_call_id`, `sample_rate:16000`, and `legs.customer` and `legs.agent`, each containing `participant_id`, `language` and `voice`. Choose any two different supported languages; read `hello.languages` for each language code and accepted/default voices, and `hello.synthetic_audio_tested_pairs` for the narrow completed synthetic audio checks. Equal languages are rejected before recognition opens. Audio is mono PCM16 little endian, base64 encoded in JSON `audio.append` with `leg`, current `epoch`, zero-based increasing `sequence` and `audio`. Each frame is at most 200ms.

Available languages: Bengali (bn), English (en), French (fr), German (de), Gujarati (gu), Hindi (hi), Italian (it), Japanese (ja), Kannada (kn), Korean (ko), Mandarin Chinese (zh), Portuguese (pt), Punjabi (pa), Russian (ru), Spanish (es), Telugu (te), Urdu (ur). Hindi/English and Punjabi/English have completed synthetic audio checks; other pairs are available to try and have not yet completed those checks. Availability does not establish human translation quality, accent coverage or ten-call capacity.

Stable translated phrases produce `translation.committed`, `audio.chunk` and `audio.completed` before the speaker finishes. Source `transcript.committed` fragments have independent character offsets; `source_context_id` attributes both ledgers to a stream context without implying word alignment. `input.commit` optionally ends the current source context; it is not required to start translated speech.

Provide separate dry participant input legs. The listener input is gated during translated playback. Report actual playback with `playback.report` (`utterance_id`, `target_epoch`, `status`, `played_samples`); cancellation does not prove playback stopped. Respect `input.gated` and `input.resumed`, and physically clear playback before a required `playback.cleared` acknowledgement after a transfer. `leg.replace` preserves epoch/revision fencing. Close with `session.end`.

Billing is connected session time for both directions together, including silence, under `interpret.minutes`. Rejected upgrades are not billed. Transcripts remain in the client; this endpoint does not persist a customer journey or integrate a PBX automatically.

## Other responses

- `101`: Authenticated interpretation WebSocket; only pyai.v1 is echoed.
- `401`: Missing or invalid API key (`code: unauthorized`)
- `402`: Insufficient available credit.
- `403`: Key lacks the required scope or the origin is not allow-listed (`code: forbidden | origin_not_allowed`)
- `429`: Rate or concurrent session limit reached.

---

[API](https://skmtc.dev/pyai/apis/pyai-api.md) · [All operations](https://skmtc.dev/pyai/apis/pyai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/pyai/apis/pyai-api/revisions/271a1539185b?raw)
