Agent-readable docs index: /docs/llms.txt. Full docs in one file: /docs/llms-full.txt. Download /docs/docs.zip to grep all markdown files locally.

TypeScript SDK

@ruut/voice-sdk is a typed, tested client for the Ruut Voice REST API, TwiML builder, and webhook verification. It runs in Node.js and browsers.

Install

npm install @ruut/voice-sdk

Quickstart

import { RuutVoice, VoiceResponse } from "@ruut/voice-sdk"; const client = new RuutVoice({ accountSid: process.env.RUUT_ACCOUNT_SID, authToken: process.env.RUUT_AUTH_TOKEN, baseUrl: "https://voice.ruut.chat", timeoutMs: 10_000, maxRetries: 2, }); // Make a call with inline TwiML const call = await client.calls.create({ to: "+2348000000001", from: "+2348000000002", twiml: new VoiceResponse().say("Hello from Ruut Voice!").toXml(), statusCallback: "https://app.example.com/calls/status", });

Client resources

ParameterTypeDescription
client.callsCreate, list, fetch, update, redirect, hold, resume, transfer, move to conference, waitFor.
client.messagesSend and list SMS messages.
client.recordingsList, fetch, and build media URLs (WAV/MP3) — including transcription fields.
client.incomingPhoneNumbersProvision, list, update, remove numbers.
client.availablePhoneNumbersSearch the number inventory.
client.agentExtensionsProvision extensions, get credentials, update presence.
client.twimlBuild TwiML with VoiceResponse.

Calls

// Create await client.calls.create({ to, from, twiml | url, statusCallback }); await client.calls.createSipCall({ sipUri, from, url }); await client.calls.createAgentCall({ agentUsername, sipDomain, from, twiml }); // Read await client.calls.list({ status, pageSize }); await client.calls.get("CA…"); // Control await client.calls.redirect("CA…", { twiml }); await client.calls.hold("CA…", "https://hold-music.mp3"); await client.calls.resume("CA…", { url }); await client.calls.transfer("CA…", "+2348000000003", { callerId }); await client.calls.moveToConference("CA…", "support-room"); // Poll until a terminal state const done = await client.calls.waitFor("CA…", { statuses: ["completed", "busy", "failed"], timeoutMs: 60_000, });

Recordings & transcripts

const recs = await client.recordings.list({ callSid: "CA…" }); const rec = await client.recordings.get("RE…"); console.log(rec.transcription_status); // "completed" console.log(rec.transcription_provider); // "whisperx" for (const seg of rec.transcription_segments ?? []) { console.log(`${seg.speaker}: ${seg.text}`); } const wav = client.recordings.mediaUrl("RE…", { format: "wav" }); const mp3 = client.recordings.mediaUrl("RE…", { format: "mp3" });

Webhooks

import { parseWebhook, isTerminalWebhook, isTranscriptionWebhook, parseTranscriptionSegments, validateWebhookSignature, } from "@ruut/voice-sdk"; const valid = await validateWebhookSignature({ url, params: req.body, signature: req.headers["x-twilio-signature"], authToken: process.env.RUUT_AUTH_TOKEN, }); if (!valid) return res.status(403).end(); const payload = parseWebhook(req.body); if (isTerminalWebhook(payload)) { /* call done */ } if (isTranscriptionWebhook(payload)) { const segments = parseTranscriptionSegments(payload); }

Error handling

import { RuutApiError, RuutTimeoutError, RuutValidationError } from "@ruut/voice-sdk"; try { await client.calls.get("CA…"); } catch (err) { if (err instanceof RuutApiError) { console.error(`API ${err.status}: ${err.message} (${err.code}, request ${err.requestId})`); } }