API

Webhooks

Receive signed call lifecycle events with automatic retry and HMAC SHA-256 validation.

Interactive Signature Verifier

💡
Test and verify your HMAC signature calculation in real time using the interactive sandbox at /docs/api.

Subscribed events

EventTrigger conditionKey payload data
call.startedRecipient answers and telephony connectscallId, agentId, direction, callerNumber, calledNumber
call.endedCall reaches terminal completed stateComplete call record with duration, transcript, and charges
call.failedCall fails to connect or times outError message, destination, endReason
transcript.readyPost-call speech and structured processing finishesFinal sanitized transcript and structured JSON extraction

Signature verification (Node.js)

Vozon signs every webhook using your secret (whsec_...). Validate X-AI-Voice-Signature before processing the body:

javascript
import { createHmac, timingSafeEqual } from "node:crypto";

export function verifyVozonSignature(rawBodyBuffer, signatureHeader, endpointSecret) {
  const expected = createHmac("sha256", endpointSecret)
    .update(rawBodyBuffer)
    .digest("hex");
  const received = signatureHeader.replace(/^v1=/, "");
  return (
    expected.length === received.length &&
    timingSafeEqual(Buffer.from(expected), Buffer.from(received))
  );
}

Signature verification (Python)

python
import hmac
import hashlib

def verify_vozon_signature(raw_body_bytes, signature_header, endpoint_secret):
    expected = hmac.new(
        endpoint_secret.encode('utf-8'),
        raw_body_bytes,
        hashlib.sha256
    ).hexdigest()
    received = signature_header.removeprefix("v1=")
    return hmac.compare_digest(expected, received)

Signature verification (Go)

go
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"strings"
)

func VerifyVozonSignature(rawBody []byte, signatureHeader string, secret string) bool {
	mac := hmac.New(sha256.New, []byte(secret))
	mac.Write(rawBody)
	expected := hex.EncodeToString(mac.Sum(nil))
	received := strings.TrimPrefix(signatureHeader, "v1=")
	return hmac.Equal([]byte(expected), []byte(received))
}

Delivery best practices

1

Return HTTP 200 promptly

Acknowledge the webhook with a 2xx status code in under 5 seconds. Offload slow operations (database writes, emails) to background queues.

2

Deduplicate with X-AI-Voice-Delivery

Vozon includes a unique delivery UUID in the X-AI-Voice-Delivery header. Store this ID to guarantee idempotent handling.

3

Automatic retry policy

If your server fails or returns non-2xx, deliveries are retried at +1m, +5m, +30m, +2h, and +12h.