Skip to main content
KugelAudio exposes an ElevenLabs-compatible HTTP API, so any existing integration built for ElevenLabs works by changing one line: the base_url. No other code changes required.

Quick Start

Python SDK

Node.js SDK

Migrating from ElevenLabs

The only changes needed:
  1. Replace base_url — point to your KugelAudio server
  2. Update voice_id — use KugelAudio voice IDs (not ElevenLabs IDs)
  3. Update output_format — use a PCM format for lowest overhead, or MP3 for integrations that require ElevenLabs’ default response shape (see Output Formats)
List your available voices to get the right IDs:

Migrating a streaming integration

ElevenLabs’ text_chunker flushes on every internal trigger; their WebSocket protocol is forgiving of mid-stream flushes because each flush is comparatively cheap. KugelAudio’s /ws/tts/stream is not: each flush triggers a fresh model prefill. The mechanical translation — “flush=True on KugelAudio == flush=true on ElevenLabs” — is the single most common source of bad TTFA when porting an existing ElevenLabs integration. See Chunking & per-segment latency for why. The right translation:

Output Formats

KugelAudio generates audio natively at 24 kHz PCM16. Lower sample rates use server-side resampling. MP3 output is encoded server-side for ElevenLabs-compatible tools that expect audio/mpeg.

Open WebUI

Open WebUI’s ElevenLabs TTS path sends Accept: audio/mpeg and saves the response as an .mp3 file. KugelAudio honors that header on /11labs/v1/text-to-speech/{voice_id} and returns audio/mpeg MP3 bytes when no explicit output_format query parameter is present.

Optional client-side G.711 conversion

KugelAudio can emit ulaw_8000 and alaw_8000 directly. If you need to convert an existing PCM stream client-side, resample to 8 kHz first:

Supported Endpoints

Text-to-Speech

About stream-input: Feed text tokens as they arrive from an LLM — synthesis starts as soon as a sentence boundary is detected, minimizing time-to-first-audio. The server sends ElevenLabs-format audio frames ({"audio": "<base64>", "isFinal": false}), then {"audio": "", "isFinal": true}, then closes the WebSocket with code 1000. That normal close is required for the official ElevenLabs Python SDK (convert_realtime), which keeps reading until the server closes (it does not stop on isFinal alone).

Voices

Other

Available Models

You can also pass the KugelAudio model ID directly: kugel-3.

Parameter Mapping

Troubleshooting

Python SDK

Native KugelAudio SDK with full feature access

JavaScript SDK

Native KugelAudio SDK with full feature access