xAI
Realtime speech-to-text with XAISTTService, over xAI's WebSocket API.
Overview
XAISTTService: streams audio over a persistent WebSocket to xAI's speech-to-text endpoint. Interim results and chunk finals becomeInterimTranscriptionFrames; the utterance final becomes aTranscriptionFrame.
Upstream page
Pipecat's documentation for the same service.
Source
packages/xai/src/stt.ts.
xAI docs
The voice API reference.
Installation
bun add @pipedog/xaiimport { XAISTTService } from "@pipedog/xai/stt";Prerequisites
- An xAI account and an API key from the xAI console.
- Pass the key as
apiKey. The examples read it fromXAI_API_KEY.
XAISTTService
Connects to wss://api.x.ai/v1/stt, with the key as a Bearer token on the handshake.
Configuration
Prop
Type
Settings
Runtime-updatable settings, passed as settings: new XAISTTService.Settings({...})
(XAISTTSettings). Any setting you leave out keeps the default below.
| Setting | Type | Default | Description |
|---|---|---|---|
model | string | "grok-voice-transcribe-2.0" | Transcription model. |
language | Language | null | Language.EN | Language of the audio, sent as a two-letter code. |
interimResults | boolean | true | Partial transcripts about every 500 ms. |
endpointing | number | null | null | Silence, in ms (0 to 5000), that ends an utterance. The server default is 400. |
multichannel | boolean | null | null | Transcribe each interleaved channel on its own. Needs channels of 2 or more. |
channels | number | null | null | Number of interleaved channels (2 to 8). |
diarize | boolean | null | null | Attach a speaker to each word. |
Usage
import { STTUpdateSettingsFrame } from "@pipedog/core/frames/frames";
import { XAISTTService } from "@pipedog/xai/stt";
const stt = new XAISTTService({
apiKey: process.env.XAI_API_KEY ?? "",
settings: new XAISTTService.Settings({ endpointing: 300 }),
});Change settings mid-call with an STTUpdateSettingsFrame:
// Queue it on the worker, or push it from a processor upstream of the service.
const update = new STTUpdateSettingsFrame({
delta: new XAISTTService.Settings({ endpointing: 500 }),
});Event handlers
| Event | Description |
|---|---|
on_connected | The WebSocket connected. |
on_disconnected | The WebSocket closed. |
Notes
encodingis"pcm"(16-bit little-endian) by default;"mulaw"and"alaw"also work.sampleRatedefaults to the pipeline's input rate.- Settings are query parameters of the connection, so any settings change reconnects.
- Audio is only sent once the server reports the session ready (
transcript.created).
Runtime notes
| Runtime | Works | What it needs |
|---|---|---|
| Bun | ✅ yes | Nothing. |
| Node.js | ✅ yes | Nothing. |
| Deno | ✅ yes | Nothing. |
| Cloudflare Workers | ✅ yes | Nothing. |
Generated from pipecat.runtimes and pipecat.compat in packages/xai/package.json: ✅ means the compat smoke test passes on that runtime.
- The WebSocket goes through the core
websocketConnect, with headers on the handshake. It works on Bun, Node, Deno and Cloudflare Workers. - Tested against a local WebSocket server, as upstream's tests do, not against xAI itself.
pipedog is an unofficial community TypeScript port of Pipecat. It is not affiliated with or endorsed by Daily or the Pipecat project.
Portions adapted from the Pipecat documentation, Copyright (c) 2024–2025 Daily, BSD-2-Clause (see apps/docs/LICENSE-pipecat-docs).