Grok Speech API Tutorial: TTS and STT at $4.20/1M Chars

At $4.20 per million characters, xAI’s new Grok text-to-speech endpoint is roughly 24x cheaper than ElevenLabs Multilingual v2 โ€” and it went live on April 17, 2026 with no waitlist, currently in Beta, and an OpenAI-compatible URL pattern. Thirteen days in, the developer reaction has been less “interesting research preview” and more “I just changed one line and saved $958 a month.”

This xAI Grok TTS API Python tutorial walks through the working code for both endpoints โ€” TTS at api.x.ai/v1/tts and speech-to-text at api.x.ai/v1/stt โ€” alongside the pricing math and a candid framework for when the switch makes sense. The same infrastructure already runs Grok Voice in Tesla vehicles and SpaceX’s Starlink customer support hotline. This isn’t a research preview. It’s a production stack that xAI just opened up to anyone with an API key.

Developer reaction to the April 17 launch settled on a consistent theme: built something with this in an afternoon. The endpoints are simple. The economics are not subtle.

The Pricing Math: What $4.20 per Million Characters Actually Means

Strip out the marketing and the comparison normalizes to a single unit: dollars per million characters of synthesized audio. Grok TTS is the cheapest entry on the board by a margin that doesn’t require a calculator to notice.

Provider / ModelPrice per 1M charactersMultiple vs Grok
Grok TTS$4.201.0x
OpenAI tts-1$153.6x
OpenAI tts-1-hd$307.1x
ElevenLabs Flash/Turbo$5011.9x
ElevenLabs Multilingual v2$10023.8x

Run the scenario for a product generating 10 million characters per month โ€” roughly a daily 30-minute podcast feed or a moderately busy documentation narration system. On Grok, that’s $42 a month. On ElevenLabs Multilingual v2, it’s $1,000. The annual delta is $11,496 โ€” enough to fund roughly a quarter of a junior engineer’s time, redirected from voice synthesis API fees to literally anything else.

STT pricing tells a more nuanced story. Grok charges $0.10 per hour for batch transcription and $0.20 per hour for streaming. Deepgram Nova-3 Monolingual streaming runs roughly $0.29 per hour (Pay-As-You-Go), ElevenLabs Scribe v1/v2 is $0.22 per hour, and AssemblyAI Universal-2 batch sits at $0.15 per hour โ€” slightly below Grok’s batch rate. The gap vs the TTS comparison is much narrower: at 1,000 hours of monthly streaming, Grok runs about $90/month less than Deepgram Nova-3.

This is the DeepSeek playbook applied to audio: undercut by an order of magnitude, ship endpoints that match the incumbent’s URL pattern, and let migration scripts decide the market. One honest caveat โ€” Grok offers no voice cloning and ships with five fixed voices. ElevenLabs’ premium is partly justified by cloning, voice similarity search, and emotional fine-tuning. The price comparison is fair only for generic narration workloads where “the voice” isn’t the product.

xAI Grok TTS API Python Tutorial: Voices, Speech Tags, and Your First Audio File

The lowest-friction way to test the API is curl. Three lines, one command, an MP3 in your working directory:

curl -X POST https://api.x.ai/v1/tts \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello from Grok TTS!", "voice_id": "eve", "language": "en"}' \
  --output hello.mp3

The Python equivalent is equally compact. Note that the response body is binary MP3, so write it directly to a file rather than calling .json():

import os
import requests

response = requests.post(
    "https://api.x.ai/v1/tts",
    headers={
        "Authorization": f"Bearer {os.environ['XAI_API_KEY']}",
        "Content-Type": "application/json",
    },
    json={
        "text": "Hello from Grok TTS!",
        "voice_id": "eve",
        "language": "en",
    },
)
response.raise_for_status()

with open("hello.mp3", "wb") as f:
    f.write(response.content)

Five voices ship with the API. Eve is the default โ€” energetic and upbeat. Ara is warm and friendly. Rex reads as confident and clear. Sal sits smooth and balanced in the middle. Leo is authoritative and strong. Voice IDs are case-insensitive, which is a small kindness from whoever shipped the parser.

The feature that genuinely separates Grok from OpenAI’s flat tts-1 delivery is inline speech tags. You write them directly in the text payload: "That's [laugh] actually a great point. <whisper>Don't tell anyone.</whisper>" OpenAI TTS has no equivalent โ€” you get the words read back, nothing more.

The inline catalog covers emotion and pause markers โ€” [pause], [laugh], [chuckle], [sigh], [breath], and others. Wrapping tags control delivery style: <whisper>, <loud>, <slow>, <fast>, <emphasis>, and pitch/intensity variants. For anyone building voice agents on the OpenAI Agents SDK, these tags map cleanly to expressive prompt patterns.

The official TTS documentation confirms 20-language support with a useful language: "auto" option for detection. The REST endpoint caps requests at 15,000 characters; default output is MP3 at 24 kHz / 128 kbps, with WAV, PCM, ฮผ-law, and A-law also available. For real-time pipelines, wss://api.x.ai/v1/tts drops the per-request character limit entirely (15K per delta), with 50 concurrent sessions per team.

Illustration: Grok Speech API

Grok STT Tutorial: Transcription, Diarization, and Word Timestamps

STT swaps JSON for multipart upload. Unlike the TTS endpoint, the request shape uses multipart form fields rather than a JSON body. The model field is set to grok-stt in examples from xAI’s launch, though xAI’s reference docs describe the endpoint by its required file fields:

curl -X POST https://api.x.ai/v1/stt \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -F model=grok-stt \
  -F file=@meeting.wav \
  -F format=json \
  -F language=en \
  -F diarize=true

The Python version uses the files parameter on requests.post for the multipart upload:

import os
import requests

with open("meeting.wav", "rb") as audio:
    response = requests.post(
        "https://api.x.ai/v1/stt",
        headers={"Authorization": f"Bearer {os.environ['XAI_API_KEY']}"},
        data={
            "model": "grok-stt",
            "format": "json",
            "language": "en",
            "diarize": "true",
        },
        files={"file": audio},
    )

transcript = response.json()
for word in transcript["words"]:
    print(f"[{word['speaker']}] {word['start']:.2f}s: {word['text']}")

Three features matter for real workloads. Speaker diarization tags every word with a speaker field, so you can reconstruct who-said-what without a separate model. Word-level timestamps include both start and end times โ€” useful for clip generation and search indexing. Multichannel transcription processes up to eight channels independently, which solves the call-center scenario where each line is its own audio stream.

The STT API reference documents 25-26 supported languages and auto-detection across 12 audio formats โ€” WAV, MP3, FLAC, MP4, OGG, Opus, AAC, M4A, MKV, plus raw PCM, ฮผ-law, and A-law. The file size ceiling is 500 MB per request. For streaming, wss://api.x.ai/v1/stt delivers interim results roughly every 500ms with 100 concurrent sessions per team and a 10 RPS ceiling. This is the layer where developers building voice-enabled agent pipelines can plug in transcription without standing up Whisper themselves.

One number deserves an asterisk. xAI reports a 5.0% phone-call entity error rate for Grok STT vs ElevenLabs at 12.0%, Deepgram at 13.5%, and AssemblyAI at 21.3%, with a 2.4% WER on video and podcast audio. Those numbers come from xAI’s own launch announcement and have not been independently replicated as of April 30, 2026. The spread is large enough that even a partial replication would still favor Grok โ€” but treat the headline figure as a vendor claim, not a verified benchmark.

Migration from OpenAI: One Line of Code

The migration path from OpenAI is genuinely a single base URL change. Same Bearer auth, same parameter shape, same SDK calls. xAI’s migration guide puts it bluntly: “Migrating is as easy as generating an API key and changing a URL.”

# Before: OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

# After: Grok (only the base_url changes)
client = OpenAI(
    api_key=os.environ["XAI_API_KEY"],
    base_url="https://api.x.ai/v1",
)

ElevenLabs migration is not a one-liner. Different parameter names (voice_id vs voice), a different auth header format (xi-api-key vs Bearer), and different output handling all require code changes. The Voice Agent API (model grok-voice-think-fast-1.0) also ships compatible with OpenAI’s Realtime API spec, with an official xAI LiveKit Plugin for real-time pipelines. For anyone weighing this against a broader stack rebuild, our AI agent framework comparison for 2026 covers the orchestration layer.

When to Use Grok Speech (and When to Stick with ElevenLabs)

The decision splits cleanly along workload type rather than provider loyalty.

  • Switch to Grok for high-volume generic narration (documentation readers, news playback, accessibility tooling, podcast intros), call center transcription pipelines, multilingual apps needing 20+ language coverage, and any workload where monthly TTS costs exceed $50 on ElevenLabs.
  • Stay on ElevenLabs for products where the voice is the product โ€” character.ai-style apps, audiobooks with licensed voice talent, branded voice assistants requiring custom cloning, or any workflow that depends on ElevenLabs’ emotional fine-tuning controls.
  • STT decision is simpler: the price gap is narrower than TTS โ€” Grok streaming at $0.20/hr compares to Deepgram Nova-3 at ~$0.29/hr and ElevenLabs Scribe at $0.22/hr โ€” but if xAI’s phone-audio benchmarks survive third-party testing, that’s a genuine differentiator for call center, medical, and financial transcription.

The capability gap is real even when the pricing case is decisive. Five fixed voices, no cloning, no custom model training, no voice similarity search. As Open TechStack framed it in their launch analysis: “By cutting prices by 2 to 10 times compared with ElevenLabs, AssemblyAI, and OpenAI TTS, xAI is clearly signaling that AI audio is becoming a commodity.” Commoditization is great for buyers of generic narration. It is less great if you were paying ElevenLabs specifically for the things ElevenLabs does that Grok doesn’t.

The Question That Still Needs an Answer

Here’s the part that reframes the launch: xAI doesn’t actually need audio to be profitable. It needs developers to swap their base URL to api.x.ai exactly once. Every future Grok model โ€” text, vision, code, agent โ€” then becomes a one-line addition rather than a vendor evaluation. Audio is the loss-leader. The OpenAI-compatible endpoint is the moat. Charging $4.20 per million characters isn’t a pricing strategy; it’s a recruitment strategy disguised as one.

The first independent benchmark replication of Grok STT’s phone-call entity recognition โ€” when a researcher publishes test results against the same audio set xAI used โ€” will either validate the 4x accuracy claim or expose it as dataset selection. That’s the data point that decides whether Grok STT actually wins call center transcription at scale, or whether the price advantage stalls at the 30-second-demo stage. Watch the third-party speech benchmark leaderboards through Q3 2026.

Get the Daily Pulse

Sharp analysis on what's actually moving in AI. No hype, no filler, no weekly digest.

Get the Daily Pulse

Sharp AI analysis, daily. Two minutes, every morning.

Get the Daily PulseTwo minutes, every morning