API reference
The ker-ai Malayalam voice API in full — authentication, session configuration, REST endpoints, the WebSocket voice protocol, the tool-call loop, errors, and rate limits.
This is the primary integration surface for ker-ai. Everything the service does is reachable here over REST and a WebSocket.
Base URL & authentication
Your invite includes a base URL (e.g. https://api.kerai.io) and an API key.
Authenticate every request with a bearer token:
For the WebSocket, pass the same key as a bearer token on the upgrade request (or as documented for your client). Keep keys server-side; never ship them in a public bundle.
Session configuration
Every voice session is described by a config object, validated on both client and server.
Required
| Field | Type | Notes |
|---|---|---|
mode | string | client_text or server_audio. |
language | string | BCP-47, e.g. ml-IN. |
llmProvider | string | Language-model provider id. |
llmModel | string | Model id within that provider. |
debug | boolean | Emit verbose diagnostics. |
Optional
voice, sttProvider, sttModel, ttsProvider, ttsModel,
streamResponse, temperature, systemPromptOverride, tools[].
REST endpoints
GET /health
Liveness probe. Returns 200 with a small JSON body when the service is up.
GET /api/providers/catalog
The speech, language, and voice providers and models available to your key, so a client can offer a picker without hardcoding ids.
WebSocket voice protocol
The live channel is a WebSocket at /ws/voice. The client streams microphone
audio (or text) up; the service streams transcripts, assistant text, synthesized
audio, and tool calls back. Every message is { "type": "...", "payload": { ... } }.
Client → server
Server → client
The tool-call loop
- The server emits
function.callwith anid, the toolname, and parsedarguments. - The client runs the matching handler and replies with
function.resultcarrying the sameid. - The server folds the result into the model and continues — usually with
assistant.textand, inserver_audio,assistant.audio.
Utterance-based chunking is fine: send a complete spoken turn as audio chunks, then let the server transcribe and respond. Continuous low-latency streaming is not required for a good experience.
Errors
Failures surface two ways:
- REST — a non-
2xxstatus with a JSON{ "message": "..." }body.401means a missing or invalid key;429means you hit a rate limit. - WebSocket — an
errorevent ({ "type": "error", "payload": { "message" } }) for problems mid-session (unsupported language/voice, malformed audio, provider timeout). The socket may close after a fatal error; reconnect and re-session.init.
Rate limits
Each plan sets a request rate (per minute) and a cap on concurrent sessions; over
either, requests are rejected with 429. The limits for your plan are listed on
the pricing comparison and returned in your account.