VOICE / get-a-tts-voice-via-api

Voice

Get a TTS voice via the xAI API

Fetch metadata for one built-in Text to Speech voice when you already know its voice_id and need the canonical name and language without downloading the full catalog. Official Voice REST reference documents GET https://api.x.ai/v1/tts/voices/{voice_id} with Bearer API-key auth. A successful response returns voice_id, name, and optional language for that built-in, matching the objects returned by the collection list. This path is for the shared built-in roster; team-owned clones use GET https://api.x.ai/v1/custom-voices/{voice_id} instead (Get a custom voice via the xAI API).

What you need

An xAI API key and a built-in voice_id such as eve or another id from List TTS voices via the API or the console voice playground. Neighboring jobs include Pick built-in voices for the Grok Voice API, Convert text to speech with the Voice API, and Set TTS output format via the xAI API. More voice jobs live on the Voice hub.

Request a single built-in voice

Export the key, then GET by path segment with no request body:

export XAI_API_KEY="your_api_key"
export VOICE_ID="eve"

curl -s "https://api.x.ai/v1/tts/voices/${VOICE_ID}" \
  -H "Authorization: Bearer ${XAI_API_KEY}"
import json
import os

import requests

voice_id = "eve"
response = requests.get(
    f"https://api.x.ai/v1/tts/voices/{voice_id}",
    headers={"Authorization": f"Bearer {os.environ['XAI_API_KEY']}"},
)
response.raise_for_status()
print(json.dumps(response.json(), indent=2))

Expect a compact object such as:

{
  "voice_id": "eve",
  "name": "Eve",
  "language": "en"
}

Use the returned voice_id on unary POST /v1/tts as voice_id, on streaming TTS as the voice query parameter, or on Speech to Speech session.voice. The language field on the voice object describes the voice record; synthesis still requires you to pass request language (BCP-47 or auto) because any built-in voice can speak every supported language per the Text to Speech guide.

When to get versus list

Call this single-voice GET in deploy checks and support tooling that already store a voice_id and only need to confirm the built-in still resolves with the expected display name. Prefer List TTS voices via the API when you are populating a picker or discovering every built-in id. Prefer the Custom Voices GET when the id came from clone creation or console Copy Voice ID on a team card — those ids are absent from /v1/tts/voices/{voice_id}.

Pitfalls

Hitting this endpoint with a custom clone id returns not-found style failures even though the clone works on POST /v1/tts; switch to /v1/custom-voices/{voice_id}. Treating voice language as a substitute for the required TTS request language field drops the BCP-47 (or auto) value the synthesize endpoints demand. Caching a single GET forever without a refresh leaves dashboards showing a display name after the service updates the roster — re-fetch on boot or when a synthesize call rejects the id. Never log full API keys beside voice metadata in shared support dumps.