VOICE / enable-stt-speaker-diarization

Voice

Enable speaker diarization on speech-to-text

Enable speaker diarization on speech-to-text

Set diarize so each word in the STT response carries a speaker integer. Works on mixed mono when you need who-said-what without separate channel tracks. Base batch and stream flows: Transcribe audio with the Voice API and Stream speech to text over WebSocket.

Batch REST

POST https://api.x.ai/v1/stt. diarize is a boolean (default false). Put option fields before file in the multipart body.

curl -X POST https://api.x.ai/v1/stt \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -F diarize=true \
  -F file=@/path/to/meeting.wav

When diarize=true, each entry in words includes speaker (integer) alongside text, start, and end.

{
  "text": "Hello. Hi there.",
  "words": [
    { "text": "Hello.", "start": 0.0, "end": 0.4, "speaker": 0 },
    { "text": "Hi", "start": 0.8, "end": 1.0, "speaker": 1 },
    { "text": "there.", "start": 1.0, "end": 1.3, "speaker": 1 }
  ]
}

Streaming WebSocket

Add diarize=true as a query param on wss://api.x.ai/v1/stt. Word objects in transcript.partial / finals include speaker the same way.

wss://api.x.ai/v1/stt?sample_rate=16000&encoding=pcm&interim_results=true&diarize=true

Proxy the WebSocket through your backend so the API key stays off the client.

Multichannel audio

When the recording already has discrete tracks (agent on channel 0, customer on channel 1), see Transcribe multichannel speech-to-text. Diarization labels speakers on a single mixed stream; multichannel returns a channels array with per-track text.

Pitfalls

  • speaker appears on words only when diarize=true.
  • Console API credits are separate from SuperGrok's weekly pool on grok.com.
  • Never put the API key in client-side WebSocket code; proxy through your backend.