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

# .wave Speech-to-Text

> Streaming STT with WaveSTTService over .wave's Deepgram-compatible WebSocket API, with interim results and multilingual support.

> [!NOTE]
>
> **Community-maintained integration.** This service is built and
> maintained by
> [.wave](https://github.com/dotwave-ai)
> . Pipecat does not test or officially support it. Please report issues and
> request changes on the
> [source repository](https://github.com/dotwave-ai/pipecat-dotwave)
> . Learn more about
> [community integrations](https://docs.pipecat.ai/api-reference/server/services/community-integrations.md)
> .

## Overview

`WaveSTTService` provides streaming speech-to-text through
[.wave](https://dotwave.ai/), over its `/v1/listen` WebSocket, a
Deepgram-compatible streaming transcription endpoint. The service extends
Pipecat's `WebsocketSTTService` and pushes `InterimTranscriptionFrame` and
`TranscriptionFrame` results into the pipeline. When the VAD reports the end of
speech, it sends `Finalize` and marks the answering transcription as finalized.

> [card] [Source Repository](https://github.com/dotwave-ai/pipecat-dotwave)
>
> Source code, README, and issues for the .wave integration

> [card] [Example](https://github.com/dotwave-ai/pipecat-dotwave/blob/main/examples/transcription-dotwave.py)
>
> Transcribe a browser microphone in a single file

> [card] [.wave Socket Reference](https://dotwave.ai/docs/deepgram/)
>
> Messages, parameters, languages, and close codes

> [card] [.wave](https://dotwave.ai/)
>
> Create an account and an API key

> [card] [PyPI Package](https://pypi.org/project/pipecat-dotwave/)
>
> The `pipecat-dotwave` package on PyPI

## Installation

This is a community-maintained package distributed separately from `pipecat-ai`:

```bash theme={null}
uv add pipecat-dotwave
```

## Prerequisites

### .wave Account Setup

Before using the .wave STT service, you need:

1. **.wave Account**: Sign up at [dotwave.ai](https://dotwave.ai/)
2. **API Key**: Create an API key in the .wave console

### Required Environment Variables

* `DOTWAVE_API_KEY`: Your .wave API key for authentication

## Configuration

**api\_key** `str` *required*

.wave API key, sent as `Authorization: Token <key>`.

**base\_url** `str` (default: api.dotwave.ai)

API endpoint: a bare host, or a URL with a scheme such as
`ws://localhost:8080`. A bare host uses `wss`.

**encoding** `str` (default: linear16)

Encoding sent on the socket: `"linear16"`, `"mulaw"`, or `"alaw"`. Pipeline
audio is converted as needed: `linear16` is sent at 16 or 24 kHz (other rates
are resampled to 16 kHz), `mulaw` and `alaw` at 8 kHz.

**sample\_rate** `int` (default: None)

Sample rate of the incoming audio in Hz. If `None`, uses the pipeline's input
sample rate.

**utterance\_end\_ms** `int` (default: None)

Silence in milliseconds (1000 to 3200) after which the socket ends a segment
on its own, sending a final with `speech_final` and an `UtteranceEnd` message.
If `None`, segments end on `Finalize`, which the service sends when the VAD
reports the end of speech.

**interim\_results** `bool` (default: True)

Whether to receive interim results.

**extra\_headers** `dict[str, str]` (default: None)

Additional headers for the WebSocket handshake. Merged after the default
headers, so they can override them.

**segment\_finals** `bool` (default: True)

Push one `TranscriptionFrame` per segment, holding the whole segment, with
`InterimTranscriptionFrame`s carrying the segment so far. `False` pushes one
frame per socket result instead, often one word at a time. See "How results
arrive" under [Notes](#notes).

**settings** `WaveSTTService.Settings` (default: None)

Runtime-updatable settings. See [Settings](#settings) below.

**ttfs\_p99\_latency** `float` (default: None)

P99 latency from speech end to final transcript, in seconds, used by turn
strategies. .wave has not measured this value for Pipecat, so Pipecat's
default applies if `None`. Measure your deployment with
[stt-benchmark](https://github.com/pipecat-ai/stt-benchmark) and pass the
result.

### Settings

Runtime-configurable settings passed via the `settings` constructor argument
using `WaveSTTService.Settings(...)`. These can be updated mid-conversation with
`STTUpdateSettingsFrame`; a change reconnects the socket.

| Parameter | Type | Default | Description |
| - | - | - | - |
| `model` | `str` | `"nemotron-asr-streaming"` | Transcription model. |
| `language` | `Language \| str \| None` | `None` | Language to transcribe. `None` or `"multi"` selects automatic language detection. |
| `extra` | `dict` | `{}` | Additional query parameters, sent as given. A parameter the socket refuses is reported as an error. |

## Usage

### Basic Setup

```python theme={null}
import os

from pipecat_dotwave import WaveSTTService

stt = WaveSTTService(api_key=os.getenv("DOTWAVE_API_KEY"))

# ... add stt to your pipeline, after a VAD
```

### With a Language and a Segment Rule

```python theme={null}
import os

from pipecat.transcriptions.language import Language

from pipecat_dotwave import WaveSTTService

stt = WaveSTTService(
    api_key=os.getenv("DOTWAVE_API_KEY"),
    utterance_end_ms=1000,
    settings=WaveSTTService.Settings(language=Language.PT_BR),
)
```

### Telephony Audio

```python theme={null}
import os

from pipecat_dotwave import WaveSTTService

stt = WaveSTTService(
    api_key=os.getenv("DOTWAVE_API_KEY"),
    encoding="mulaw",
)
```

## Notes

* **VAD required for timely finals**: Put a VAD upstream of the service (a
  `VADProcessor`, or the user aggregator's VAD). On `VADUserStoppedSpeakingFrame`
  the service sends `Finalize`, and the transcription that answers it is pushed
  with `finalized=True`.
* **How results arrive**: The socket sends a final as soon as words are
  settled, often one word at a time. By default the service collects them and
  pushes one `TranscriptionFrame` per segment. A segment ends when the socket
  answers `Finalize` (the frame is marked `finalized`), when a final is marked
  `speech_final` or an `UtteranceEnd` arrives (with `utterance_end_ms`), or when
  the service stops or reconnects with words pending. While a segment is open,
  each interim and each final pushes an `InterimTranscriptionFrame` with the
  segment so far, so turn strategies and RTVI clients show live text. Finals
  join with one space, except in Chinese and Japanese where they join with no
  separator. With `segment_finals=False`, each socket result is its own frame.
* **Languages**: A Pipecat `Language` is sent as the tag the socket expects.
  Regional values pass through (`Language.PT_BR` as `pt-BR`), `Language.EN` is
  sent as `en` (English, United States), and a bare code with a single regional
  variant is sent as that variant (`Language.DE` as `de-DE`). You can also pass
  a tag string such as `"pt-BR"`. A language .wave does not serve is refused when
  the socket opens, with an error naming the tags it does serve. Frames carry
  the reported language as a Pipecat `Language`, and none with automatic
  detection.
* **Not supported**: `diarize`, `multichannel`, `channels`, `keywords`, and
  `endpointing`. Passing them to the constructor raises `TypeError`.
* **Keepalive**: A session closes after 30 seconds without audio, so the service
  sends a short burst of silence after 20 idle seconds.
* **Errors**: `Error` messages from the socket are pushed as `ErrorFrame`. A
  refused API key (close code 4401) or a malformed request (4400) is permanent
  and not retried; other closes reconnect with backoff.
* **Pricing**: \$0.00045 per minute of audio. See
  [pricing and limits](https://dotwave.ai/docs/pricing-and-limits/).

## Event Handlers

`WaveSTTService` supports the standard service connection events:

| Event | Description |
| - | - |
| `on_connected` | Connected to the .wave socket |
| `on_disconnected` | Disconnected from the socket |
| `on_connection_error` | A connection error occurred |

```python theme={null}
@stt.event_handler("on_connected")
async def on_connected(service):
    print("Connected to .wave")
```

## Compatibility

Tested with Pipecat v1.12.0 and pipecat-dotwave 0.1.1. Requires Pipecat 1.12.0 or later and Python 3.11 or
later. Check the [source repository](https://github.com/dotwave-ai/pipecat-dotwave)
for the latest tested version and changelog.


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