Get character timestamps from Text to Speech
Get character timestamps from Text to Speech
Set with_timestamps: true on POST https://api.x.ai/v1/tts when you need captions, karaoke highlights, or lip-sync. The response switches from raw audio bytes to a JSON envelope with base64 audio plus per-character timing.
Request
import base64, os, requests
response = requests.post(
"https://api.x.ai/v1/tts",
headers={"Authorization": f"Bearer {os.environ['XAI_API_KEY']}"},
json={
"text": "Hello world.",
"voice_id": "eve",
"language": "en",
"with_timestamps": True,
},
)
response.raise_for_status()
payload = response.json()
open("hello.mp3", "wb").write(base64.b64decode(payload["audio"]))
ts = payload["audio_timestamps"]
for char, (start, end) in zip(ts["graph_chars"], ts["graph_times"]):
print(f"{char!r:>5} {start:.2f}s – {end:.2f}s")
print(f"duration: {payload['duration']:.2f}s")
Response shape
| Field | Meaning |
|---|---|
audio |
Base64 audio in the requested codec |
content_type |
MIME type (e.g. audio/mpeg) |
duration |
Total seconds |
audio_timestamps.graph_chars |
Each input character in order (spaces, punctuation, speech tags) |
audio_timestamps.graph_times |
Parallel [start, end] pairs in seconds |
graph_chars[i] lines up with graph_times[i]. Step the arrays together; do not slice the original string by byte index when text_normalization expands symbols ($5 stays two characters while spoken as "five dollars").
Streaming
Open wss://api.x.ai/v1/tts?…&with_timestamps=true. Each audio.delta can carry audio_timestamps and audio_duration for the characters in that chunk.
Pitfalls
- Timestamps add a post-synthesis alignment pass, so latency goes up.
- With a
replacemap,graph_charsfollows the spoken (replaced) text. - Decode
audioyourself; do not treat the JSON body as a playable file. - Never call TTS from the browser with the long-lived API key.
- Console API credits are separate from SuperGrok's weekly pool on grok.com.