import base64
import json
import os
from pathlib import Path
from urllib.request import Request, urlopen
payload = {
"contents": [
{
"parts": [
{
"text": "Welcome to MixRoute.",
"speechMetadata": {
"style": "Warm, clear and unhurried."
}
}
]
}
],
"generationConfig": {
"responseModalities": [
"AUDIO"
],
"speechConfig": {
"voiceConfig": {
"prebuiltVoiceConfig": {
"voiceName": "Kore"
}
}
}
}
}
request = Request(
"https://api.mixroute.ai/v1/models/gemini-3.8-flash-tts:generateContent",
data=json.dumps(payload).encode("utf-8"),
headers={
"Authorization": "Bearer " + os.environ["MIXROUTE_API_KEY"],
"Content-Type": "application/json",
},
method="POST",
)
with urlopen(request, timeout=120) as response:
result = json.load(response)
audio = next((
part["inlineData"]
for candidate in result.get("candidates", [])
for part in candidate.get("content", {}).get("parts", [])
if part.get("inlineData", {}).get("mimeType", "").startswith("audio/")
), None)
if not audio:
reasons = [c.get("finishReason") for c in result.get("candidates", [])]
raise RuntimeError(f"No audio: finishReason={reasons}; promptFeedback={result.get('promptFeedback')}")
mime_type = audio["mimeType"].split(";", 1)[0].strip().lower()
if mime_type not in ("audio/wav", "audio/x-wav"):
raise RuntimeError(f"Expected WAV, received {mime_type}")
wav = base64.b64decode(audio["data"], validate=True)
if wav[:4] != b"RIFF" or wav[8:12] != b"WAVE":
raise RuntimeError("The audio data is not a WAV file")
Path("speech.wav").write_bytes(wav)
print("speech.wav")