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")

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" }

Authorization

Bearer credential

Send the credential in the Authorization header. Account and voice keys are accepted only where the endpoint contract permits them.

Security

The stream-token response carries the socket URL. Use that value rather than a hard-coded origin, and confirm with the operator that it resolves to a public wss endpoint before you ship an integration.

Request

FieldTypeRequiredDefaultDescription
type"start"Yes-Must be start.
textstringYes-Must not exceed the max_length carried by the token.
languagestringNoautoauto, or one code or full name from the 646-language catalog.
speednumberNo1.0Clamped 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 codes

Was this page helpful?

Evom Labs API documentation