Loly 3.5
Text-to-Speech (WebSocket)
Streams PCM16 mono at 24 kHz, in frames of roughly 200 ms.
WS
/ws/tts/stream?token=<stream_token>On this page
Code examples
import json, requests, websocket
BASE_URL = "https://studio.evomlabs.com"
API_KEY = "vc_sk_live_YOUR_KEY"
text = "Xin chào, đây là bài test giọng nói."
# 1. Ask for a short-lived token. It expires in 60 seconds, so open the
# socket immediately afterwards.
token = requests.post(
f"{BASE_URL}/api/v1/tts/stream-token",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"text_length": len(text)},
).json()["data"]
# 2. Always connect to the ws_url the response returned.
ws = websocket.create_connection(f"{token['ws_url']}?token={token['stream_token']}")
ws.send(json.dumps({"type": "start", "text": text, "language": "vi"}))
pcm = bytearray()
while True:
frame = ws.recv()
if isinstance(frame, bytes):
pcm.extend(frame) # PCM16 mono at 24 kHz
continue
event = json.loads(frame)
if event["type"] in ("done", "error", "cancelled"):
break
ws.close()
print("received", len(pcm), "bytes of audio")Request
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
type | "start" | Yes | - | Must be start. |
text | string | Yes | - | Must not exceed the max_length carried by the token. |
language | string | No | auto | auto, or one code or full name from the 646-language catalog. |
speed | number | No | 1.0 | Clamped to 0.5 to 1.5. |
Important
The voice is locked into the stream token. The start message cannot change it.
Response
Events
// Server to client
{ "type": "start", "mode": "fast", "sample_rate": 24000,
"format": "pcm16", "channels": 1 }
<binary frame> // PCM16 mono, about 200 ms per frame
{ "type": "done", "mode": "fast", "audio_url": "/api/tts/file/output.wav",
"chunks": 12, "ttfb_ms": 480, "duration_ms": 5230 }
{ "type": "error", "message": "Error description" }
{ "type": "cancelled" }Errors
REST failures use the documented error envelope. Handle the error code instead of matching the human-readable message.
Error codesWas this page helpful?