1npx @inkibra/voice-cli init
PLIVO_AUTH_ID and PLIVO_AUTH_TOKEN stored on your serverINKIBRA_API_KEY stored on your serverhttps:// and wss:// routesPOST https://voice.example.com/plivo/answer and its Hangup URL to POST https://voice.example.com/plivo/status. Assign the number to that Application.X-Plivo-Signature-V3, and X-Plivo-Signature-V3-Nonce. Also handle X-Plivo-Signature-Ma-V3 when the account has multiple auth tokens.nonce, store it with the expected CallUUID, and return:12345678910<?xml version="1.0" encoding="UTF-8"?> <Response> <Stream keepCallAlive="true" bidirectional="true" contentType="audio/x-mulaw;rate=8000" statusCallbackUrl="https://voice.example.com/plivo/status"> wss://voice.example.com/plivo/media/NONCE </Stream> </Response>
/plivo/media/:nonce, then confirm that the WebSocket start event contains the expected call identity.start, pass the connected media socket to your Plivo audio transport and connect Inkibra:123456789import LiveVoice from "@inkibra/voice-sdk/server"; const session = await LiveVoice.connect({ apiKey: process.env.INKIBRA_API_KEY!, audio: new PlivoAudioTransport(plivoSocket), prompt: "Answer questions about the customer's order.", conversation: { starts: "assistant" }, tools: {}, });
LiveVoice.connect creates, prepares, and starts the Inkibra session. The transport class implements the provider-specific audio mapping in the next step.media event:media.payload as PCMU at 8 kHz.enqueue command, command.pcm is PCM16LE mono at 24 kHz. Keep mode: "buffer" chunks private until the matching release. Downsample released audio to 8 kHz, mu-law encode, then send:12345678plivo.send(JSON.stringify({ event: "playAudio", media: { contentType: "audio/x-mulaw", sampleRate: 8000, payload: pcmuAudio.toString("base64"), }, }));
generationId. After the SDK's done command, call handlers.receipt with event: "started" when playout begins and event: "completed" when your 24 kHz playout clock reaches the end. On cancel, discard unsent chunks, send Plivo clearAudio, and return a cancelled receipt with the number of 24 kHz samples actually played. Honor block-foreground, release, and reaction-versus-foreground lanes exactly as described in Server media.stop, the Hangup callback, or either WebSocket closing:12session.stop(); await session.closed;
CallUUID. Treat a media disconnect as terminal until your application implements explicit session resumption. If Inkibra sends session.limit, a provider error, or closes the WebSocket, clear queued Plivo audio and end the call.POST /v1/sessions request.release.clearAudio, a cancelled receipt, and no stale audio after the interruption.session.stop, both sockets closed, and the nonce/call record removed.