A session establishes a real-time voice connection with Kallglot. The example below uses a Kallglot-managed number because it is the fastest setup path.
Request shape: use routing, not provider. For POST /v1/sessions, telephony selection belongs under routing (phone_number, connection_id, or SIP fields per Create Session). The session response may include a string field provider (for example "twilio") describing which carrier was resolved—that is not something you send as provider: { "type": "twilio", ... } in the request body. Older samples that used a nested provider object for outbound creation are not the public contract; integrations should always follow routing.
Language auto-detection: source_language and target_language are optional. When omitted, Kallglot infers each speaker’s language from the audio. Set them explicitly when you already know the pair for more predictable startup behavior.
Successful POST /v1/sessions requests currently consume 1 API credit. Check X-API-Credits-Remaining and X-API-Credits-Used in the response headers to track usage. If the organization subscription is inactive, the API returns 403 organization_inactive. If credits are exhausted, it returns 402 insufficient_api_credits.
The session response includes a WebSocket URL for real-time streaming. The token expires in 5 minutes, so connect promptly. Once connected, token expiry does NOT terminate the stream.
async function connectToSession(sessionId, streamToken) { const ws = new WebSocket( `wss://api.kallglot.com/v1/sessions/${sessionId}/connect?token=${streamToken}` ); ws.onopen = () => { console.log('Connected to Kallglot stream'); }; ws.onmessage = (event) => { const data = JSON.parse(event.data); switch (data.type) { case 'session.ready': console.log('Session ready'); break; case 'transcript.partial': console.log(`[Partial] ${data.speaker}: ${data.text}`); break; case 'transcript.final': console.log(`[${data.speaker}] ${data.text}`); if (data.translation) { console.log(` → ${data.translation.text}`); } break; case 'audio.output': // Play translated audio playAudio(data.audio.payload); break; case 'session.ended': console.log('Session ended:', data.reason); ws.close(); break; case 'error': console.error(`Error [${data.code}]: ${data.message}`); break; } }; return ws;}// Send audio to the streamfunction sendAudio(ws, audioBase64, speaker) { ws.send(JSON.stringify({ type: 'audio.input', sequence: Date.now(), timestamp_ms: Date.now(), speaker: speaker, audio: { encoding: 'mulaw', sample_rate_hz: 8000, payload: audioBase64 } }));}