Get started →
Documentation

Webhooks overview

Ruut Voice notifies your application about call and recording lifecycle events by making HTTP requests to URLs you configure. Every webhook can be verified with a signed signature.

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 callStatusCallback on call creation.
  • Per numberstatusCallback / recordingStatusCallback on an incoming phone number.
  • Per TwiML verb<Record transcribeCallback>, <Dial recordingStatusCallback>.

Delivery & retries

Webhooks are delivered with POST by default. Failures are retried with exponential backoff. Your endpoint should return a 2xx to acknowledge; anything else triggers a retry.

Signature verification

Every request is signed with HMAC-SHA1 of the URL + sorted parameters, using your account's Auth Token as the key. Verify before trusting the payload:

Examplets

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);
ℹ️ The header is X-Twilio-Signature (Twilio-compatible). Always validate it — it prevents spoofed callbacks.

Express helper

The SDK ships an Express middleware that validates signatures and parses the payload for you:

Examplets

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);
  }
);