Skip to main content
Webhooks deliver platform events to your endpoint as signed HTTPS POSTs. One subscription covers one or more event types; Yotel fans out each event to every matching subscription.

Subscribe

Subscriptions are managed via the dashboard (Supabase JWT auth), not via the /api/v1/* path. We decided early on that webhook management is a human operation that shouldn’t be scripted by customer backends.
  1. Dashboard → Developer → Webhooks
  2. Click New subscription
  3. Enter your HTTPS URL (HTTP is rejected at the DB layer)
  4. Pick event types from the catalog
  5. On save, copy the signing_secretshown once
You can have multiple subscriptions — e.g. one for call.ended to your warehouse, another for campaign.paused to your on-call Slack.

Event envelope

Every delivery is a POST with:
POST /your-url HTTP/1.1
Content-Type: application/json
X-Zetta-Event: call.ended
X-Zetta-Delivery: 3c8f4a9b-7d11-4c8d-9a2e-1b3e5f6a7c12
X-Zetta-Timestamp: 1744934400
X-Zetta-Signature: sha256=abc123…

{
  "event_id": "1f2e...",
  "event_type": "call.ended",
  "timestamp": 1744934400,
  "data": {
    "call_id": "c-1234",
    "campaign_id": "camp-567",
    "lead_id": "l-890",
    "hangup_cause": "NORMAL_CLEARING",
    "talk_duration_s": 42,
    "disposition": "interested",
    "recording_url": "https://storage.googleapis.com/yotel-recordings/..."
  }
}

Expectations for your endpoint

Requirement
ProtocolHTTPShttp:// URLs are rejected at subscribe time
TimeoutRespond within 10s — we cancel the request after that
SuccessReturn 2xx to mark the delivery delivered
Temporary failureReturn 408, 429, or 5xx → we retry
Permanent failureReturn other 4xx → we dead-letter immediately (no retry)
OrderingNone guaranteed — key on event_id for idempotent processing

Retries

Failed deliveries retry on this schedule (±10% jitter):
AttemptDelay
1 → 2+5s
2 → 3+30s
3 → 4+3m
4 → 5+15m
5 → 6+1h
6 → 7+6h
7DEAD — no more retries
Total retry window: ~7.5 hours. If your endpoint is down longer than that for a specific event, it’s gone from the queue — you’ll need to reconcile state from your side using the relevant REST endpoints. After 20 consecutive failures AND no successful delivery in 24h your subscription is auto-disabled. You’ll need to manually re-enable from the dashboard.

Troubleshooting

Your dashboard’s Webhooks → Delivery log shows every delivery attempt with HTTP status, response snippet, and duration. If signatures don’t verify on your side, 95% of the time it’s clock skew — see signature verification.

Next