Skip to content

v0.2.0 — Custom Voice support (48h after xAI shipped the API)

Choose a tag to compare

@Wolfe-Jam Wolfe-Jam released this 02 May 00:42

xAI announced their Custom Voices API on 2026-05-01. We shipped support 48 hours later.

This release fulfills the v0.2.0 Identity roadmap slot — your voice is now part of your identity, alongside your namepoint and Voice key.

Added

  • CustomVoiceClient — sync HTTP client for xAI's Custom Voices API. Voice CRUD (create_voice, list_voices, get_voice, update_voice, delete_voice, download_reference_audio) plus text_to_speech synthesis. Built on httpx.Client — no new dependencies.

    from grok_faf_voice import CustomVoiceClient
    
    cv = CustomVoiceClient()  # uses $XAI_API_KEY
    
    # Clone a voice from a 90-120s WAV sample
    voice = cv.create_voice("sample.wav", name="My Clone", language="en")
    
    # Synthesize TTS with the cloned voice
    cv.text_to_speech(
        "Hello from the new voice",
        voice_id=voice["voice_id"],
        output_path="hello.mp3",
    )
  • Custom voice IDs accepted by VoiceAgent(voice=...). The validator now recognizes both the five built-in voices (case-insensitive: Ara, Eve, Leo, Rex, Sal) AND custom voice IDs (the 8-character lowercase alphanumeric IDs returned by CustomVoiceClient.create_voice()). The voice_id parameter flows through unchanged into the LiveKit / xAI realtime layer — xAI accepts either form on the same endpoint.

    from grok_faf_voice import VoiceAgent
    VoiceAgent(voice="nlbqfwie").run()  # custom-cloned voice
  • examples/hello_custom_voice.py — end-to-end demo showing voice clone → VoiceAgent integration in the same two-line shape.

Changed

  • Validation error message expanded to guide users to xAI's Custom Voices docs when an unrecognized voice is passed. Built-in voice acceptance is now case-insensitive at the SDK boundary (matches xAI API behavior).

Notes

  • XAI_API_KEY is the only credential needed for CustomVoiceClient — same key as VoiceAgent. Voice IDs you create persist on your xAI account and can be reused across sessions, devices, and SDK versions.
  • The 30 free voices available via the xAI console work too — pass their voice_id directly to VoiceAgent(voice=...) or CustomVoiceClient.text_to_speech().
  • No breaking changes to the v0.1.3 surface. Existing two-line VoiceAgent().run() code keeps working unchanged.

Quality

  • 169 tests passing, 4 skipped (network-gated). Up from ~136 in v0.1.3.
  • 19 new tests covering custom voice validation + HTTP layer.
  • FAF score: 🏆 TROPHY 100% / 9/9 slots.

xAI gave Grok Voice. We gave Grok memory.

FAF defines. MD instructs. AI codes.