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

# Language support

> Which languages PyAI supports on Hear, Omni, Speak, and Dub today, including staged availability and explicit unsupported-language behavior.

This page is the single source of truth for **which languages work on which
product today**. We publish what is GA and benchmarked, what is accepted but not
yet measured, and what is roadmap, so you can plan an integration without
guessing.

<Info>
  **Short version:** Availability differs by product. Omni
  currently serves `en`, `fr`, `es`, and `hi`. `de` is accepted but currently
  falls back to English. Hear synchronous and streaming transcription serves
  `en`, `es`, `fr`, `de`, `hi`, `it`, `pt`, and `nl`. Automatic language detection is the default; an explicit language pins
  recognition for the request or session. Cue is unavailable on the serving Hear
  stream.
</Info>

## Status at a glance

| Product | English | Other languages | Native non-English voices |
| - | - | - | - |
| **Hear**, speech-to-text | GA · benchmarked | Sync + streaming: `es` / `fr` / `de` / `hi` / `it` / `pt` / `nl` (automatic by default; optional explicit `language`). Async jobs: the same eight languages, auto-detected per call | n/a |
| **Dub**, audio dubbing | `en` / `es` / `fr` / `de` / `hi` / `it` / `pt` / `nl` source audio | `en` / `es` / `fr` / `de` / `hi` / `it` / `pt` / `zh` / `ja` / `ko` / `ru` output audio | Live capabilities report the supported direction set |
| **Cue**, turn detection + KB grounding | **Unavailable** | **Unavailable** | n/a |
| **Omni**, agentic voice (STT + brain + TTS) | GA · Standard plus Natural `en1` | `fr` / `es` / `hi` served. `de` currently falls back to English | French, Spanish, and Hindi Standard session voices |
| **Speak**, text-to-speech | GA · Standard plus Natural `en1` | Catalog language groups: `en` / `es` / `fr` / `de` / `it` / `pt` / `ru` / `zh` / `ja` / `ko` / `hi` / `gu` / `te` / `pa` / `kn` / `bn` / `ur`. A catalog group is not a cross-product guarantee. | Inspect `available_on`, `synthesis_modes`, account access, and the effective delivery response on every catalog row |

**Legend.** *GA · benchmarked* = supported and we publish accuracy numbers.
*Rejected loudly* = a language outside the published set fails with
`400 unsupported_language` instead of being silently mis-transcribed.
*Roadmap* = planned, not available today.

## Dub (audio dubbing)

Dub accepts source codes `en`, `es`, `fr`, `de`, `hi`, `it`, `pt`, and `nl`, and
can render `en`, `es`, `fr`, `de`, `hi`, `it`, `pt`, `zh`, `ja`, `ko`, or `ru`.
Read `GET /healthz/dub` before enabling a production direction: that endpoint
is the live source of truth, and published codes do not promise equivalent
quality for every direction. Validate your recordings before using a new
source-language workflow in production.

Submit with `POST /v1/dub`, poll until `done` or `error`, then download the audio.
See [the Dub guide](/guides/dub-overview) for the complete asynchronous workflow.

## Hear (speech-to-text)

The streaming endpoint (`GET /v1/audio/transcriptions/stream`) and the
OpenAI-compatible sync endpoint (`POST /v1/audio/transcriptions`) accept an
optional `language` parameter:

```
GET /v1/audio/transcriptions/stream?protocol=pyai-hear-v1&model=pyai-hear&language=auto&sample_rate=16000&encoding=pcm16
```

* `language` is an ISO-639-1 code: `en`, `es`, `fr`, `de`, `hi`, `it`, `pt`,
  or `nl`; streaming also accepts `auto`. Other explicit values are rejected with `400 unsupported_language`.
* Omit `language` for automatic detection on synchronous or streaming transcription. Streaming also accepts `language=auto`.
* An explicit language code pins recognition for the complete request/session. In automatic streaming mode, recognition starts fresh at utterance boundaries, allowing a later utterance to use a different language. Mixed-language accuracy still depends on the recording; this is not a guarantee of error-free code-switching.
* **English** is the GA, benchmarked language. Published English accuracy:
  **\~1.6% WER on clean audio** and **\~4.8% WER on an 8 kHz telephony/accented
  corpus** (see [Benchmarks](https://pyai.com/benchmarks)).

<Note>
  Async batch jobs (`POST /v1/transcription/jobs`) take **no STT language**:
  the spoken language is **auto-detected per call** across the same eight
  languages (`en`/`es`/`fr`/`de`/`hi`/`it`/`pt`/`nl`) and the transcript is
  returned in the detected language. The API does not currently return the
  detected language code. The optional `language` field sets the **Recap
  summarization** language (`en`/`fr`/`es`/`de`/`hi`) and does not affect
  transcription. Use Hear sync/streaming when you need to pin the decode
  language explicitly.
</Note>

### Indian languages & code-mixed speech

Hindi (`hi`) is accepted on Hear sync and streaming. PyAI does **not yet
publish** Hear word-error-rate numbers for Hindi, Italian, Portuguese, or
Dutch, nor for **code-mixed Hinglish / Tanglish**. Tamil, Telugu, Bengali,
Marathi, Kannada, Malayalam, Gujarati, Punjabi, and other codes outside the
published set are rejected outright (`400 unsupported_language`). Omni serves
Hindi/Hinglish end to end (see below).

**Output script.** With `language=hi`, the transcript is rendered in
**Devanagari — including English words** spoken mid-sentence (`check` →
`चेक`). If your traffic is Hinglish or otherwise heavily code-mixed and your
pipeline expects Latin script, sending `language=en` yields mostly-Latin
output, and on our measurements it also gives **better word accuracy** on
code-mixed Indian calls than `language=hi`. The `vocabulary`/context feature
biases recognition toward your terms but does **not** steer the output
script: listing a Latin-spelled term does not stop it from being rendered in
Devanagari under `language=hi`.

<Warning>
  If your product depends on Indian-language or code-mixed transcription accuracy,
  **validate on your own audio before committing.** Talk to us and we will run a
  joint accuracy evaluation against your real call samples, that measurement is
  the right go/no-go signal, not this page. The benchmark harness we use for this
  lives in the repo at `evals/benchmarks/hear-multilingual.benchmark.json`.
</Warning>

Hear does not currently expose language-identification or decoder-confidence
fields. On sync and streaming, omitting `language` enables automatic detection;
the streaming endpoint also accepts `language=auto`. Send the known language
when your product requires recognition to stay pinned for the full
request/session. Only async batch jobs report no language-selection field at
all: they auto-detect each call.

## Omni (agentic voice)

Omni runs the full loop: speech-to-text, the brain, and text-to-speech. The
configuration enum is `en` (default), `fr`, `es`, `de`, and `hi`, and the
currently served set is `en`, `fr`, `es`, and `hi`. Set a served language once on the
Agent profile and every call on that Agent requests it:

```bash theme={null}
curl https://api.pyai.com/v1/agents \
  -H "Authorization: Bearer $PYAI_API_KEY" \
  -d '{ "name": "Agente de Ventas", "language": "es" }'
```

* `language` is an **agent-level** setting (an agent is "a Spanish agent").
  It can also be sent per session in the `configure` frame, which wins over
  the profile (see the [Omni protocol reference](/realtime/omni-protocol)).
  Absent or `null` means `en`, exactly the pre-multilingual behavior.
* **Availability is staged per language.** As of 2026-08-13, German is not
  enabled on the public fleet. Configuring an Agent for German falls back to English and the
  call proceeds (the `configured` ack reports `language_active` and
  `language_fallback: true`), and the call bills as what was actually served.
  Treat the ack as authoritative and close the session if fallback is not
  acceptable.
* Hindi uses the Standard voice tier. See the [pricing page](https://pyai.com/pricing)
  for current tier treatment. Choose
  `hi1` through `hi4` (or the canonical ids from `GET /v1/voices`). Omit
  `voice_id` for `hi1`, the default. A bad Hindi id also serves the default,
  and `configured.voice_id` reports the canonical voice actually served.
  Stock ids ending in `_en_in` remain Indian-English voices, not Hindi.
* English Natural uses `en1` (canonical id `stock_aria_en`). Omni reports the
  canonical id and `voice_tier: "natural"` in the configured acknowledgement
  while that tier is active. See the [pricing page](https://pyai.com/pricing)
  for current tier treatment.
* Per-phone-number language mapping and automatic language detection are
  fast-follows, not part of this rollout.

Language availability is specific to each product. A voice available on Speak
does not automatically extend Omni or Hear language support. Check the catalog's
`available_on` field before using the same voice on another product.
For a language outside each product's published set, bring recognition and
synthesis that support it. Do not treat omitted Hear language as unbounded
language support: it requests automatic detection only inside the published set.

## Speak (text-to-speech)

`GET /v1/voices` is the unified catalog. Inspect `available_on` before using a
row. `POST /v1/audio/speech` has no separate `language` parameter; the selected
voice determines the language. The catalog groups and aliases are:

| Language | Code | Example voice alias |
| - | - | - |
| English | `en` | `en1` |
| Spanish | `es` | `es1` |
| French | `fr` | `fr1` |
| German | `de` | `de1` |
| Italian | `it` | `it1` |
| Portuguese | `pt` | `pt1` |
| Russian | `ru` | `ru1` |
| Mandarin Chinese | `zh` | `zh1` |
| Japanese | `ja` | `ja1` |
| Korean | `ko` | `ko1` |
| Hindi | `hi` | `hi1` |
| Gujarati | `gu` | `gu1` |
| Telugu | `te` | `te1` |
| Punjabi | `pa` | `pa1` |
| Kannada | `kn` | `kn1` |
| Bengali | `bn` | `bn1` |
| Urdu | `ur` | `ur1` |

Catalog discovery is the source of truth for a configuration you can select.
Every Speak voice accepts `stream: true` and `stream: false`, but request
acceptance is different from incremental delivery: a voice served from a
blocking-only fleet answers a streaming request successfully with
`x-pyai-stream: buffered`. Inspect that response header before treating a
request as low-latency playback. Delivery checks establish availability, not a
pronunciation guarantee for every name, number, accent, or mixed-language
passage. Test your intended text and voice together.

* English Natural `en1` (`stock_aria_en`) supports streaming and buffered
  Speak synthesis. Tier and count summaries are catalog projections, not a
  promise that every source row is available to every account or product.
* Hindi Standard `hi1`–`hi4` works on both Speak and Omni (it was published as
  Omni-only until 2026-09-07; Speak served it the whole time). The former Hindi
  Natural aliases `hi5`–`hi8` are retired and no longer served.
* See the [pricing page](https://pyai.com/pricing) for current Speak voice-tier
  treatment.

Indian-English voices (filter `?region=india`) speak English. They are not
Hindi voices.

## How accuracy gets published

We gate engine quality in CI with an offline benchmark harness (`evals/`) and
publish the headline numbers on the [Benchmarks](https://pyai.com/benchmarks)
page. As languages are measured, their numbers appear there and this matrix is
updated. If you need a number that isn't published yet, ask, an unpublished
number means "not measured to our bar," not "hidden."

## See also

<CardGroup cols={2}>
  <Card title="Speech To Text (Hear)" href="/guides/hear-overview">Choose sync, streaming, or timestamped async transcription.</Card>
  <Card title="Text To Speech (Speak)" href="/guides/speak-overview">Choose a catalog voice and compatible delivery mode.</Card>
  <Card title="Omni wire protocol" href="/realtime/omni-protocol">Connect, configure, and the live-vs-roadmap field table.</Card>
  <Card title="Telephony audio (8 kHz)" href="/reference/telephony-audio">μ-law ↔ PCM16 at 8 kHz for phone legs.</Card>
  <Card title="Pricing" href="https://pyai.com/pricing">Current rates, included usage, and plan availability.</Card>
</CardGroup>


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