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.

Webhooks overview

Ruut Voice notifies your application about call and recording lifecycle events by making HTTP requests to URLs you configure. Signing and retry behavior varies by callback type.

What you can receive

EventTriggerReference
Call statusCall state changes (ringing, in-progress, completed…)call status
RecordingRecording in-progress / completed / absentrecordings
TranscriptionTranscription completed / failed (with speaker segments)transcriptions

Where to set callback URLs

  • Per call — StatusCallback on call creation.
  • Per number — statusCallback / recordingStatusCallback on an incoming phone number.
  • Per TwiML verb — <Record transcribeCallback>, <Dial recordingStatusCallback>.

Delivery & retries

Delivery method depends on the callback configuration. Recording delivery jobs have bounded retries; the current call-status callback job logs errors and does not retry failed HTTP requests itself. Return a 2xx promptly and reconcile important state through the API.

Signature verification

Recording and transcription callbacks use the Twilio-compatible signing workflow: HMAC-SHA1 of the URL and sorted parameters, keyed by the account Auth Token. The current call-status callback job does not use that workflow and does not add this header. Confirm the callback type before relying on signature verification:
import { parseWebhook, validateWebhookSignature } from "@ruut/voice-sdk"; const valid = await validateWebhookSignature({ url: "https://app.example.com/webhooks/call-status", params: req.body, // parsed form params signature: req.headers["x-twilio-signature"], authToken: process.env.RUUT_AUTH_TOKEN, }); if (!valid) return res.status(403).end(); const payload = parseWebhook(req.body);
For callbacks that use the signing workflow, validate the X-Twilio-Signature header before trusting the payload. Do not assume the unsigned call-status callback is authenticated.

Express helper

The SDK ships an Express middleware that validates signatures and parses the payload for you:
import { ruutWebhook } from "@ruut/voice-sdk/express"; app.post("/webhooks/call-status", ruutWebhook({ authToken: process.env.RUUT_AUTH_TOKEN }), (req, res) => { const call = req.ruutWebhook; console.log(call.CallStatus, call.CallSid); res.sendStatus(200); } );