Developers · SDK · CLI · self-hosted API
Add voices to your app. Pay nothing.
Node SDK
One package. Downloads the 82M-parameter Kokoro model on first run (~90 MB, cached), then generates speech offline on CPU.
npm install keladosimport { createKelados } from "kelados";
const kelados = await createKelados(); // runs locally, no key needed
const clip = await kelados.speak("Hello from my app!", { voice: "af_heart", speed: 1.05 });
await clip.save("hello.wav"); // or clip.toWav() → Buffer
// Stream long text sentence by sentence
for await (const chunk of kelados.stream(longChapter, { voice: "bm_george" })) {
player.enqueue(chunk.audio, chunk.sampleRate); // Float32Array @ 24 kHz
}Add an API key to use the presets and pronunciation rules from your console:
const kelados = await createKelados({
apiKey: process.env.KELADOS_API_KEY, // kel_...
baseUrl: "https://kelados.vercel.app",
});
await kelados.speak("Kelados ships SQL tooling", { preset: "Narrator" }); // lexicon applied automaticallyCLI
npx kelados speak "The quick brown fox" -v am_fenrir -o fox.wav
npx kelados speak -f chapter-01.txt -v bf_emma -s 0.95 -o chapter-01.wav
npx kelados voicesDrop-in API server
Run a local server that speaks both the /v1/audio/speech and /v1/text-to-speech/:voice dialects. Point your existing SDKs at it and you're done.
npx kelados serve --port 8880 --key my-secret
# Docker / VPS / Raspberry Pi / your laptop: anything with Node 20+curl http://localhost:8880/v1/audio/speech \
-H "Authorization: Bearer my-secret" -H "content-type: application/json" \
-d '{"model": "tts-1", "voice": "nova", "input": "Same code, zero bill."}' -o out.wavcurl http://localhost:8880/v1/text-to-speech/af_bella \
-H "xi-api-key: my-secret" -H "content-type: application/json" \
-d '{"text": "Same request, Kelados-shaped invoice: $0."}' -o out.wavCommon voice names map to Kokoro voices (alloy, echo, fable, onyx, nova, shimmer…). Output is WAV or raw PCM.
In your users' browsers
Want your web app to talk without any backend? Do what this site does: load the model in a Web Worker and let each visitor's GPU do the work.
// worker.js (type: "module")
import { KokoroTTS, TextSplitterStream } from "https://cdn.jsdelivr.net/npm/kokoro-js@1.2.1/dist/kokoro.web.js";
const tts = await KokoroTTS.from_pretrained("onnx-community/Kokoro-82M-v1.0-ONNX",
{ dtype: navigator.gpu ? "fp32" : "q8", device: navigator.gpu ? "webgpu" : "wasm" });
self.onmessage = async ({ data }) => {
const s = new TextSplitterStream(); s.push(data.text); s.close();
for await (const { audio } of tts.stream(s, { voice: data.voice }))
self.postMessage({ audio: audio.audio, rate: audio.sampling_rate });
};Our full worker lives in frontend/public/workers/tts.js in the repo. Copy it.
API keys
Create keys in the console. Send them as x-api-key: kel_… or Authorization: Bearer kel_…. Keys are stored as SHA-256 hashes, shown once, and revocable any time.
REST API
Base URL https://kelados.vercel.app. Every endpoint accepts an API key except the public stats endpoint.
| GET | /api/v1/workspace | Your presets + pronunciation lexicon (what the SDK syncs) |
| POST | /api/usage | { characters, seconds, source } logs usage to your dashboard |
| GET | /api/usage?days=30 | Daily usage rows and totals |
| GET/POST | /api/projects | List / create long-form projects |
| GET/PUT/DELETE | /api/projects/:id | Read, replace or delete a project |
| GET/POST | /api/presets | List / create voice presets |
| PUT/DELETE | /api/presets/:id | Update / delete a preset |
| GET/PUT | /api/lexicon | Read / replace pronunciation rules |
| GET | /api/stats | Public counters (no auth) |
curl https://kelados.vercel.app/api/v1/workspace -H "x-api-key: kel_..."FAQ
Is it really unlimited?
+
Yes. Generation happens on your device, so there is no meter to run out. The only limit is how long you're willing to wait.
How good are the voices?
+
Kokoro-82M ranked #1 on the community TTS Arena at launch, beating models 10-100× its size. The A-grade voices hold up on long-form narration.
Which languages?
+
Speech: American and British English today. Transcription: 99 languages via Whisper.
Can I use the audio commercially?
+
Yes. The model is Apache-2.0 and Kelados is MIT. Output is yours.
Why do I need an account at all?
+
You don't. Accounts only sync projects, presets and pronunciation rules, and issue API keys.
Open source
Frontend, backend and SDK are MIT-licensed. Fork it, self-host it, rebrand it. Voices come from Kokoro-82M (Apache-2.0) by hexgrad; the browser runtime is transformers.js by Hugging Face.
Try the studio