sipgate-ai TTS

Self-hosted German text-to-speech with an OpenAI- and ElevenLabs-compatible API. Point any SDK that speaks either protocol at this host and it works without code changes. Multi-engine, optimised for telephony latency.

πŸ‘‰ Interactive playground β€” synthesize speech in the browser, no setup.

Endpoints

MethodPathAuthWhat
GET/healthznoLiveness check
GET/v1/modelsyesList engines + aliases
GET/v1/voicesyesList available voices
POST/v1/audio/speechyesOpenAI TTS (batch)
POST/v1/text-to-speech/{voice_id}yesElevenLabs TTS (batch)
WS/v1/realtimeyesOpenAI Realtime β€” text in, audio chunks out
WS/v1/text-to-speech/{voice_id}/stream-inputyesElevenLabs realtime β€” token-by-token text in
ALL/kugel/*yesKugelaudio native pass-through (REST + WebSocket) β€” see below

Authentication

All /v1/* endpoints require an API key (the same shared key as the STT and LLM services). Send via either header:

Authorization: Bearer <key>      # OpenAI clients
xi-api-key: <key>                 # ElevenLabs clients

Engines

Pass the engine in the model (OpenAI) or model_id (ElevenLabs) field. Unknown names β€” including provider defaults like tts-1 or eleven_multilingual_v2 β€” fall back to the default engine. Authenticated clients can list identifiers via /v1/models.

EngineNotes
qwen3-tts defaultCloned Sipgate brand voice (German)
kyutaiLowest latency β€” best for realtime telephony
omnivoiceDiffusion-LM zero-shot clone (600+ languages)
kugelaudioExternal Kugelaudio provider β€” dynamic voice selection (model kugel-3); see the native route below

Voices & formats

Select a speaker with the voice / voice_id field (see /v1/voices). Output response_format: pcm, wav, mp3, opus. Engines render at 24 kHz mono; pass sample_rate (e.g. 16000) for narrowband telephony.

Realtime streaming (WebSocket)

Two bidirectional WebSocket surfaces stream synthesized audio back as it is produced β€” playback can start after the first sentence instead of waiting for the whole text. These are not in the Swagger/OpenAPI spec below: OpenAPI cannot describe WebSocket endpoints. Audio frames are always raw s16le PCM, base64-encoded. Authenticate with the same key; browser clients that cannot set headers may pass it via the bearer.<key> subprotocol entry or a ?api_key=/?token= query param.

WS /v1/realtime β€” OpenAI Realtime

Client β†’ server (JSON): text, as one message or as deltas.
Server β†’ client (JSON): session.created, then response.audio.delta {"delta": "<base64 PCM>"} frames and a final response.audio.done.

WS /v1/text-to-speech/{voice_id}/stream-input β€” ElevenLabs Realtime

Query: output_format β€” a pcm_<rate> value resamples the stream to that rate; non-PCM values stream at the engine's native rate.
Client β†’ server (JSON): {"text": "…"} token by token, then {"text": ""} to flush and close.
Server β†’ client (JSON): {"audio": "<base64 PCM>"} per chunk and a closing {"isFinal": true}.

Kugelaudio native API pass-through

Besides the kugelaudio engine above (which fits the unified OpenAI/ElevenLabs surface), the full native Kugelaudio API is proxied 1:1 under /kugel/ β€” authenticated with the same sipgate key, then forwarded to the provider with its own credentials. Use this to reach Kugelaudio features the unified surface flattens: dynamic numeric voice IDs, word timestamps, barge-in, multi-context streaming and per-request diffusion-step control. Strip the /kugel prefix and the rest of the path is Kugelaudio's own:

MethodPathWhat
POST/kugel/v1/tts/generateNative synthesis β†’ streaming PCM (24 kHz s16le)
GET/kugel/v1/voices, /kugel/v1/modelsNative voice / model catalogue
POST/kugel/11labs/v1/text-to-speech/{voice_id}ElevenLabs-compatible surface
WS/kugel/ws/tts/streamSingle-stream realtime (word timestamps, barge-in)
WS/kugel/ws/tts/multiMulti-context realtime (up to 20 concurrent streams)
curl -X POST https://tts.sipgate.ai/kugel/v1/tts/generate \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "Guten Tag, hier ist Sipgate.", "model_id": "kugel-3", "voice_id": 963}' \
  --output out.pcm

Quick examples

OpenAI TTS (curl β†’ WAV):

curl -X POST https://tts.sipgate.ai/v1/audio/speech \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3-tts",
    "input": "Guten Tag, hier ist Sipgate. Wie kann ich Ihnen helfen?",
    "response_format": "wav"
  }' --output out.wav

ElevenLabs-style (curl β†’ PCM 16 kHz):

curl -X POST "https://tts.sipgate.ai/v1/text-to-speech/sipgate-brand?output_format=pcm_16000" \
  -H "xi-api-key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "Ein Techniker meldet sich in KΓΌrze.", "model_id": "qwen3-tts"}' \
  --output out.pcm

OpenAI Python SDK:

from openai import OpenAI

client = OpenAI(base_url="https://tts.sipgate.ai/v1", api_key=KEY)
client.audio.speech.create(
    model="qwen3-tts",
    voice="sipgate-brand",
    input="Vielen Dank fΓΌr Ihren Anruf.",
    response_format="mp3",
).stream_to_file("out.mp3")

Web UI

For an interactive chat front-end that reads answers aloud via this API, see chat.sipgate.ai.

API documentation