Skip to main content
The ElevenLabs Compatibility Proxy allows you to use KugelAudio with any application built for the ElevenLabs API. Simply change the base_url and your existing code works with KugelAudio’s TTS.

Why Use the Proxy?

  • Drop-in replacement: Use existing ElevenLabs integrations without code changes
  • SDK compatibility: Works with the official ElevenLabs Python SDK
  • WebSocket streaming: Full support for real-time text streaming
  • Voice mapping: Automatically maps ElevenLabs voice IDs to KugelAudio voices

Quick Start

Using Docker

docker run -d \
  --name elevenlabs-proxy \
  -p 8080:8080 \
  -e TTS_SERVER_WS=ws://your-tts-server:8000/ws/tts \
  -e SUPABASE_URL=https://your-project.supabase.co \
  -e SUPABASE_SERVICE_KEY=your-service-key \
  kugelaudio/elevenlabs-proxy:latest

Using Docker Compose

version: '3.8'
services:
  elevenlabs-proxy:
    image: kugelaudio/elevenlabs-proxy:latest
    ports:
      - "8080:8080"
    environment:
      - TTS_SERVER_WS=ws://tts-server:8000/ws/tts
      - SUPABASE_URL=${SUPABASE_URL}
      - SUPABASE_SERVICE_KEY=${SUPABASE_SERVICE_KEY}

Running Locally

# Install dependencies
cd backend
uv sync

# Set environment variables
export TTS_SERVER_WS=ws://localhost:8000/ws/tts
export SUPABASE_URL=https://your-project.supabase.co
export SUPABASE_SERVICE_KEY=your-service-key

# Run the proxy
uv run uvicorn src.elevenlabs_proxy.proxy:app --host 0.0.0.0 --port 8080

Configuration

Environment VariableDefaultDescription
TTS_SERVER_WSws://localhost:8000/ws/ttsWebSocket URL of your KugelAudio TTS server
TTS_SERVER_HTTPDerived from WS URLHTTP URL for health checks
SUPABASE_URLRequiredYour Supabase project URL
SUPABASE_SERVICE_KEYRequiredSupabase service role key

Usage with ElevenLabs SDK

Python SDK

from elevenlabs import ElevenLabs

# Point to the proxy instead of ElevenLabs
client = ElevenLabs(
    api_key="your-kugelaudio-api-key",
    base_url="http://localhost:8080"
)

# Use exactly like ElevenLabs!
audio = client.text_to_speech.convert(
    voice_id="your-voice-id",
    text="Hello from KugelAudio!",
    model_id="kugel-1-turbo",
)

# Save or play the audio
with open("output.mp3", "wb") as f:
    for chunk in audio:
        f.write(chunk)

Streaming TTS

from elevenlabs import ElevenLabs

client = ElevenLabs(
    api_key="your-api-key",
    base_url="http://localhost:8080"
)

# Stream audio chunks
audio_stream = client.text_to_speech.stream(
    voice_id="your-voice-id",
    text="This is streaming audio from KugelAudio.",
    model_id="kugel-1-turbo",
)

for chunk in audio_stream:
    # Play or process each chunk
    play_audio(chunk)

Real-time WebSocket Streaming

For LLM integration with real-time text streaming:
import json
import base64
from websockets.sync.client import connect

# Connect to WebSocket endpoint
ws_url = "ws://localhost:8080/v1/text-to-speech/your-voice-id/stream-input"
ws_url += "?model_id=kugel-1-turbo&output_format=pcm_24000"

with connect(ws_url, additional_headers={"xi-api-key": "your-key"}) as socket:
    # 1. Send initial config
    socket.send(json.dumps({
        "text": " ",
        "try_trigger_generation": True,
        "voice_settings": {
            "stability": 0.5,
            "similarity_boost": 0.75
        }
    }))
    
    # 2. Stream text chunks (e.g., from LLM)
    for chunk in llm_stream():
        socket.send(json.dumps({
            "text": chunk,
            "try_trigger_generation": True
        }))
    
    # 3. Signal end of input
    socket.send(json.dumps({"text": ""}))
    
    # 4. Receive audio chunks
    while True:
        data = json.loads(socket.recv())
        if data.get("audio"):
            audio_bytes = base64.b64decode(data["audio"])
            play_audio(audio_bytes)
        if data.get("isFinal"):
            break

API Endpoints

Metadata Endpoints

EndpointMethodDescription
/v1/voicesGETList all voices
/v1/voices/{voice_id}GETGet single voice
/v1/modelsGETList available models
/v1/userGETGet user info
/v1/user/subscriptionGETGet subscription info
/v1/historyGETGet generation history

Text-to-Speech Endpoints

EndpointMethodDescription
/v1/text-to-speech/{voice_id}POSTGenerate speech (full audio)
/v1/text-to-speech/{voice_id}/streamPOSTGenerate speech (streaming)
/v1/text-to-speech/{voice_id}/stream-inputWebSocketReal-time text streaming

Health & Debug Endpoints

EndpointMethodDescription
/healthGETProxy health check
/tts-healthGETTTS server health check
/configGETShow current configuration

Parameter Mapping

The proxy translates ElevenLabs parameters to KugelAudio:
ElevenLabsKugelAudioNotes
voice_idvoice_idDirect mapping
model_idmodeleleven_turbo_v2kugel-1-turbo
stabilitycfg_scaleMapped to CFG scale range
similarity_boost-Not directly mapped
output_formatsample_rateParsed from format string

Output Formats

Supported output formats:
FormatDescription
pcm_16000PCM 16-bit, 16kHz
pcm_22050PCM 16-bit, 22.05kHz
pcm_24000PCM 16-bit, 24kHz (recommended)
pcm_44100PCM 16-bit, 44.1kHz
mp3_44100_128MP3, 44.1kHz, 128kbps
ulaw_8000μ-law, 8kHz (telephony)

Migrating from ElevenLabs

Step 1: Deploy the Proxy

docker compose -f docker/elevenlabs-proxy/docker-compose.yml up -d

Step 2: Update Your Code

Change only the base_url:
# Before (ElevenLabs)
client = ElevenLabs(
    api_key="your-elevenlabs-key",
)

# After (KugelAudio via proxy)
client = ElevenLabs(
    api_key="your-kugelaudio-key",
    base_url="http://localhost:8080"
)

Step 3: Update Voice IDs

Map your ElevenLabs voice IDs to KugelAudio voice IDs. You can list available voices:
voices = client.voices.get_all()
for voice in voices.voices:
    print(f"{voice.voice_id}: {voice.name}")

Troubleshooting

Connection Issues

Check if the proxy can reach the TTS server:
curl http://localhost:8080/tts-health

Voice Not Found

Ensure the voice ID exists in your KugelAudio database:
curl http://localhost:8080/v1/voices

Audio Quality Issues

Try different output formats:
audio = client.text_to_speech.convert(
    voice_id="your-voice-id",
    text="Test audio quality",
    model_id="kugel-1-turbo",
    output_format="pcm_24000",  # Try different formats
)

Next Steps