> ## 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.

# Format Hear transcripts

> Use numerals, smart_format, and optional dictation, drop_fillers, and per-call vocabulary on Hear finals.

Hear can clean up **final** English transcripts. Interim partials are never rewritten. Every presentation step is fail-open: a timeout, exception, or lexical-guard miss returns the previous text unchanged.

<Info>
  Hear transcription is [English-only](/reference/language-support). These flags apply on sync (`POST /v1/audio/transcriptions`), streaming (`GET /v1/audio/transcriptions/stream`), and async jobs (`POST /v1/transcription/jobs`).
</Info>

## Flags

| Flag               | Default                    | What it does                                                                                                              |
| ------------------ | -------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `numerals` omitted | Engine default: **ITN on** | Spoken numbers → digits on finals (phones, currency, dates, ordinals)                                                     |
| `numerals=true`    | —                          | Force digits                                                                                                              |
| `numerals=false`   | —                          | Keep spoken form (`fifty dollars`)                                                                                        |
| `smart_format`     | **Off**                    | Sentence wrapping: capitalize, terminal `.` / `?`, conservative run-on splits, list commas, standalone `I`, tag questions |
| `dictation`        | **Off**                    | Spoken commands → punctuation (`period`, `comma`, `new paragraph`, `question mark`)                                       |
| `drop_fillers`     | **Off**                    | Strip `um`, `uh`, `umm`, `uhh`, `er`                                                                                      |
| `vocabulary`       | **Empty**                  | Per-call phrase list. Re-cases matching spans and boosts those phrases for this request only                              |

`numerals` is independent of the others. `dictation`, `drop_fillers`, and `vocabulary` are **not** implied by `smart_format`.

## `smart_format`

Opt-in. Changes **case and punctuation only**. Word identity is guarded; if wrapping would add or drop a word, Hear returns the unformatted final.

```
how much do i owe
→ How much do I owe?

hello how are you today the meeting is at 3
→ Hello how are you today. The meeting is at 3.

please send it to accounts payable and legal
→ Please send it to accounts payable, and legal.

the order is ready right
→ The order is ready right?
```

List commas keep the spoken `and`. Run-on splits are conservative: they fire only with enough words before a new clause (`the meeting/call/order/…`, `also` / `anyway` / `meanwhile`, `please send/call/…`, or a late standalone `i`). Tag questions use a short closer (`right`, `yeah`, `okay`, `isn't it`, …).

`smart_format` does **not**:

* Invent emails, URLs, or street addresses
* Expand or rewrite words (`threepm` stays `threepm` unless ITN already normalized it)
* Remove fillers (that is `drop_fillers`)
* Honor spoken "period" / "comma" (that is `dictation`)
* Format non-English text

## `dictation`

Separate from `smart_format`. Off by default. On English finals only, these spoken commands become punctuation:

* `period` → `.`
* `comma` → `,`
* `question mark` → `?`
* `new paragraph` → a paragraph break

```
hello period how are you question mark
→ hello. how are you?
```

Turn `smart_format` on as well if you also want sentence capitalization.

## `drop_fillers`

Off by default. Strips filled pauses (`um`, `uh`, `umm`, `uhh`, `er`) on English finals. **Do not enable on legal or compliance audio by default** — those tokens can be evidence.

## `vocabulary`

A **per-call** phrase list, not a stored project glossary. Max 32 phrases, 64 characters each. Matching is case-insensitive and exact; the transcript is re-cased to the form you sent, and the same list is boosted for this request only.

```
this is nguyen calling   + vocabulary=["Nguyen"]
→ This is Nguyen calling.
```

## Phone numbers

NANP grouping lives under **`numerals` / ITN**, not `smart_format`:

```
4155550172   →  415-555-0172
14155550172  →  1-415-555-0172
```

9-digit SSN-shaped spans and 16-digit card-shaped spans are never grouped.

## Surfaces

| Surface    | How to send                                                                 | When it applies                                                                                      |
| ---------- | --------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| Sync       | multipart fields                                                            | On the returned `text`                                                                               |
| Stream     | query params (SDK: `smartFormat`, `dictation`, `dropFillers`, `vocabulary`) | On `speech_final` and `final` only. `partial` stays raw.                                             |
| Async jobs | JSON `smart_format` / `dictation` / `drop_fillers` / `vocabulary`           | Once on the **stitched** transcript. `vocabulary` is also forwarded to each chunk for decoder boost. |

## Examples

<CodeGroup>
  ```bash Sync theme={null}
  curl https://api.pyai.com/v1/audio/transcriptions \
    -H "Authorization: Bearer $PYAI_API_KEY" \
    -F file=@audio.wav \
    -F model=pyai-hear \
    -F smart_format=true \
    -F vocabulary=Nguyen,SKU-99
  ```

  ```bash Stream theme={null}
  wss://api.pyai.com/v1/audio/transcriptions/stream\
  ?protocol=pyai-hear-v1&language=en&sample_rate=16000&encoding=pcm16\
  &smart_format=true
  ```

  ```python Python theme={null}
  import os
  from pyai import PyAI

  pyai = PyAI(api_key=os.environ["PYAI_API_KEY"])

  result = pyai.audio.transcriptions.create(
      file=open("audio.wav", "rb"),
      model="pyai-hear",
      smart_format=True,
      vocabulary=["Nguyen", "SKU-99"],
  )

  url = pyai.hear_stream_url(smart_format=True, dictation=True)

  job = pyai.transcription_jobs.create(
      audio_url="https://recordings.example.com/calls/abc123.wav",
      numerals=True,
      smart_format=True,
      drop_fillers=False,
      vocabulary=["Nguyen"],
  )
  ```

  ```ts Node theme={null}
  import PyAI from "@pyai/sdk";

  const pyai = new PyAI({ apiKey: process.env.PYAI_API_KEY! });

  const url = pyai.hearStreamURL({ smartFormat: true, dictation: true });

  await pyai.transcriptionJobs.create({
    audio_url: "https://recordings.example.com/calls/abc123.wav",
    numerals: true,
    smart_format: true,
    vocabulary: ["Nguyen"],
  });
  ```
</CodeGroup>

On the stream, render `partial` greyed and only commit `speech_final` / `final`. That is how you get live captions that snap to punctuated text instead of flickering punctuation on every hypothesis. See [Stream speech-to-text](/guides/streaming-stt).

## Failure behavior

Formatting is best-effort and **fail-open**. A timeout, exception, or lexical-guard miss returns the previous final unchanged. `dictation` and `drop_fillers` may change word count; when word timestamps cannot be realigned, the transcript still updates and the `words` array is cleared. Clients should not treat missing punctuation as an API error.

## Next steps

<CardGroup cols={2}>
  <Card title="Stream speech-to-text" href="/guides/streaming-stt">Partials vs finals, commit, and endpointing.</Card>
  <Card title="Conversation intelligence" href="/guides/conversation-intelligence">Batch jobs, diarization, and post-call analytics.</Card>
</CardGroup>
