Drop-in from ElevenLabs
Use ElevenLabs — text to speech, speech to speech, speech to text, sound effects and dialogue — through KhaBot. Point the official ElevenLabs SDK at KhaBot, send your KhaBot key, and pay ElevenLabs' list price from your KhaBot credit. Your code, voice ids and model ids stay the same.
Switch in two lines
| ElevenLabs | KhaBot | |
|---|---|---|
| Base URL | https://api.elevenlabs.io | https://khabot.com/api/elevenlabs |
| Key | your ElevenLabs key | kb_… — create one under API keys |
Paths stay ElevenLabs' own (/v1/…). Send the key in the xi-api-key header, as the SDKs do —
Authorization: Bearer kb_… works too.
# Python — pip install elevenlabs
from elevenlabs.client import ElevenLabs
client = ElevenLabs(
api_key="kb_YOUR_KEY", # your KhaBot key
base_url="https://khabot.com/api/elevenlabs", # instead of https://api.elevenlabs.io
)
audio = client.text_to_speech.convert(
voice_id="21m00Tcm4TlvDq8ikWAM",
model_id="eleven_multilingual_v2",
text="Your order has shipped and arrives on Thursday.",
)
with open("speech.mp3", "wb") as f:
for chunk in audio:
f.write(chunk)
// Node — npm install @elevenlabs/elevenlabs-js
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
const client = new ElevenLabsClient({
apiKey: "kb_YOUR_KEY",
baseUrl: "https://khabot.com/api/elevenlabs",
});
const audio = await client.textToSpeech.convert("21m00Tcm4TlvDq8ikWAM", {
modelId: "eleven_multilingual_v2",
text: "Your order has shipped and arrives on Thursday.",
});
curl https://khabot.com/api/elevenlabs/v1/text-to-speech/21m00Tcm4TlvDq8ikWAM \
-H "xi-api-key: kb_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "Your order has shipped.", "model_id": "eleven_multilingual_v2"}' \
--output speech.mp3
A key with a restricted service list needs ElevenLabs among its services — see Authentication.
What you can do
Paths are relative to https://khabot.com/api/elevenlabs.
| Endpoint | Does |
|---|---|
POST /v1/text-to-speech/{voice_id} | Text to speech — audio back |
POST /v1/text-to-speech/{voice_id}/stream | The same, streamed as it is generated |
POST /v1/text-to-speech/{voice_id}/with-timestamps | Audio plus per-character timings |
POST /v1/speech-to-speech/{voice_id} | Re-voice a recording |
POST /v1/speech-to-text | Transcribe audio |
POST /v1/sound-generation | Sound effects from a text prompt |
POST /v1/text-to-dialogue | Multi-voice dialogue |
GET /v1/voices, GET /v2/voices | The voices you can use (read-only) — the SDK uses /v2 |
GET /v1/voices/{voice_id}, GET /v2/voices/{voice_id} | One voice |
GET /v1/shared-voices | The shared voice library (read-only) — see Voices for which you can use |
GET /v1/models | The models, each with its credit rate |
Voices
You can use ElevenLabs' premade voices plus the voices on KhaBot's allow-list.
Custom and cloned voices aren't available. A call with any other voice id is refused with
403 voice_not_available — GET /v1/voices lists the ones you can use.
How requests are handled
- KhaBot rebuilds each request from the fields the endpoint documents.
previous_request_idsis accepted only for request ids issued to your own account. enable_logging, webhook fields and cloud-storage fields are ignored.
Limits
| What | Limit |
|---|---|
| Text to speech | Up to 40,000 characters per request |
| Speech to text uploads | Up to 25 MB and 2 hours of audio |
| Speech to speech uploads | Up to 5 MB and 5 minutes of audio |
| Requests at once, per account | Text to speech 2 · speech to text 3 · speech to speech 1 · dialogue 1 · sound effects 2 |
A request over the concurrency limit gets 429 rate_limited with a retry-after header — retry
with backoff. It is never charged.
What you cannot do yet
These answer 404 not_available (“not available via KhaBot”):
- History
- User and subscription
- Adding, editing, deleting or cloning voices
- Projects
- Dubbing
- Music
- Agents
- Workspace
- Pronunciation dictionaries
- WebSocket streaming input (
…/stream-input)
Billing
- Calls are priced in ElevenLabs credits, at ElevenLabs' list price per 1,000 credits — the current figure is on the pricing page.
- Each call costs what ElevenLabs reports for it, so the cost is exact and shows up in your usage log straight away.
- Text to speech uses about one credit per character, times the model's credit rate: 1.0 on
Multilingual v2, v3 and v4; 0.5 on Flash, Turbo, v3 Conversational and v4 Turbo.
GET /v1/modelslists each model's rate. - Speech to speech and sound effects follow ElevenLabs' own credit rules — sound effects use about 40 credits per second of audio.
- Speech to text bills by audio duration and can include a small extra charge from ElevenLabs, which is passed through at cost.
- A stream you stop early is still billed for the credits ElevenLabs charged for it.
- A call refused with
429isn't charged. - Billed from your credit only — never from a plan — and counted toward your monthly spend cap. Charges appear in your transactions as Extra usage.
- There is also a daily ElevenLabs limit per account, set by KhaBot as a brake against runaway
use and counted per UTC day. Past it, calls are refused with
402 elevenlabs_daily_cap_reacheduntil the next UTC day.
Errors
Every error on this mount — including 401 and 404 — uses ElevenLabs' own format,
so the SDKs' error handling works unchanged:
{ "detail": { "status": "voice_not_available", "message": "This voice is not available through KhaBot …" } }
| HTTP | detail.status | When |
|---|---|---|
| 400 | bad_request | A missing or invalid field — an unknown model_id, or text over 40,000 characters. The message says which |
| 401 | unauthenticated | Missing or unknown key |
| 402 | insufficient_credit | Your credit is short of the call's estimated cost — redeem a code in Billing |
| 402 | elevenlabs_daily_cap_reached | Your account reached today's ElevenLabs limit — resets at 00:00 UTC |
| 403 | elevenlabs_disabled | The ElevenLabs drop-in is switched off — voice and model listings still answer |
| 403 | service_not_allowed_for_key | This key's service list doesn't include ElevenLabs |
| 403 | voice_not_available | The voice isn't a premade voice or on KhaBot's allow-list — see Voices |
| 404 | not_available | The endpoint isn't part of the drop-in — see the list above |
| 429 | rate_limited | Too many requests to the same kind of endpoint at once — retry with backoff, after the retry-after header. Not charged. |
| 503 | upstream_unavailable | ElevenLabs couldn't be reached — safe to retry |
| 503 | service_not_configured | ElevenLabs isn't configured on KhaBot |
| 503 | service_at_capacity | The service is temporarily at capacity — try again later. Not charged |