Skip to main content

Webhooks

Webhooks let your application receive real-time notifications about events in Movoice AI. When an event occurs, we send an HTTP POST to the URL you specify.

Setting Up Webhooks

  1. Navigate to Settings → Webhooks in the Movoice Dashboard.
  2. Enter your Webhook URL (must be an https endpoint).
  3. Select which events to subscribe to.
  4. Copy your Webhook Secret for signature verification.
Use Webhook.site or ngrok during development to inspect incoming payloads before wiring up your own server.

Event Types

call.started

Triggered immediately when a call connects.
{
  "event_type": "call.started",
  "call_id": "call_998877",
  "agent_id": "agent_abc123",
  "direction": "outbound",
  "recipient_phone": "+919876543210",
  "timestamp": 1713456000
}

call.completed

Triggered when a call ends. Includes AI summary, sentiment, and transcript URL.
{
  "event_type": "call.completed",
  "call_id": "call_998877",
  "duration": 45,
  "summary": "Customer booked a dental appointment for Friday at 2 PM.",
  "sentiment": "positive",
  "outcome": "BOOKED",
  "transcript_url": "https://storage.movoice.ai/transcripts/call_998877.json",
  "recording_url": "https://storage.movoice.ai/recordings/call_998877.mp3"
}

call.failed

Triggered when a call could not be connected.
{
  "event_type": "call.failed",
  "call_id": "call_998878",
  "reason": "no_answer",
  "recipient_phone": "+919876543211",
  "timestamp": 1713456100
}
Possible reason values: no_answer, busy, invalid_number, agent_error, network_error.

action.triggered

Triggered when an agent executes a tool (e.g., “Book Appointment”, “Transfer Call”).
{
  "event_type": "action.triggered",
  "call_id": "call_998877",
  "action_name": "book_appointment",
  "parameters": {
    "date": "2026-04-25",
    "time": "14:00",
    "patient_name": "Rahul Sharma"
  }
}

transfer.initiated

Triggered when an agent initiates a warm transfer to a human agent.
{
  "event_type": "transfer.initiated",
  "call_id": "call_998877",
  "transfer_to": "+919000000001",
  "reason": "Customer requested human support"
}

Security & Verification

Every webhook request includes an X-Movoice-Signature header. Always verify this before processing:
const crypto = require('crypto');

function verifySignature(rawBody, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

// Express example
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = req.headers['x-movoice-signature'];
  if (!verifySignature(req.body, sig, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  const event = JSON.parse(req.body);
  // handle event
  res.sendStatus(200);
});

Retries

If your server returns a non-2xx response, Movoice retries the webhook with exponential backoff:
AttemptDelay
1st retry30 seconds
2nd retry5 minutes
3rd retry30 minutes
4th retry2 hours
After 4 failed attempts, the event is dropped and logged in your dashboard under Settings → Webhooks → Failed Events.