Agent skill
Ada Webhooks Skill
Receive and verify Ada (ada.cx) AI customer service webhooks, delivered through Svix. Use when setting up an Ada webhook endpoint, getting the per-endpoint whsec_ signing secret, debugging svix-id / svix-timestamp / svix-signature verification, or handling events like v1.conversation.created, v1.conversation.message, v1.conversation.ended, v1.conversation.handoff.ended, v1.end_user.created, v1.end_user.updated, v1.audit_log.emitted and v1.proactive_call.* voice outreach events.
Install this skill
npx skills add hookdeck/webhook-skills --skill ada-webhooks
Ada is an AI customer service platform. Its webhooks report conversations, messages, handoffs, end user profile changes, audit log entries and Voice Proactive Outreach calls. Ada delivers them through Svix, so every webhook is signed with svix-id, svix-timestamp and svix-signature headers.
When to Use This Skill
- How do I receive Ada webhooks?
- How do I verify an Ada webhook signature?
- Where do I find my Ada webhook signing secret?
- How do I handle
v1.conversation.created,v1.conversation.messageorv1.conversation.ended? - Why is my Ada
svix-signatureverification failing? - How do I dedupe Ada webhook retries when the payload has no event ID?
Verification (core)
| Header | Value |
|---|---|
svix-id | Unique message ID, the same on every retry |
svix-timestamp | Unix seconds of this delivery attempt |
svix-signature | v1,<base64 HMAC-SHA256>, possibly several space-separated entries |
Signed content is {svix-id}.{svix-timestamp}.{raw body}. The key is the base64-decoded part of the endpoint's secret after whsec_. Each endpoint has its own secret. Ada has no webhook SDK of its own. The examples use standardwebhooks (npm, PyPI), Svix's reference implementation of this scheme. It enforces a 5-minute timestamp tolerance and compares in constant time.
const { Webhook } = require('standardwebhooks');
// rawBody: exact request body string, NOT re-serialised JSON
function verifyAdaWebhook(rawBody, headers, secret = process.env.ADA_WEBHOOK_SECRET) {
// standardwebhooks expects webhook-* names; Ada (Svix) sends svix-*
return new Webhook(secret).verify(rawBody, {
'webhook-id': headers['svix-id'],
'webhook-timestamp': headers['svix-timestamp'],
'webhook-signature': headers['svix-signature'],
}); // returns the parsed event; throws → respond 400
}
Python: from standardwebhooks.webhooks import Webhook, then Webhook(secret).verify(await request.body(), {...same mapping...}). A dependency-free manual version is in references/verification.md.
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Event Envelope
{ "type": "v1.conversation.created", "timestamp": "2026-10-21T09:30:00.123Z",
"data": { "conversation_id": "...", "channel_id": "...", "end_user_id": "...",
"metadata": {}, "ai_agent_domain": "example.ada.support" } }
The payload has no event ID. Dedupe on the svix-id header.
Common Event Types
| Event | Fired when |
|---|---|
v1.conversation.created | A new conversation is created for a supported channel |
v1.conversation.message | A message is added (author.role: end_user, ai_agent, human_agent) |
v1.conversation.ended | A conversation ends (end endpoint called or Voice call disconnects) |
v1.conversation.handoff.ended | A handoff to a human agent integration ends |
v1.end_user.created / v1.end_user.updated | An end user is created / a profile value changes |
v1.audit_log.emitted | A configuration change is recorded in the Audit log |
v1.proactive_call.queued / .initiated / .answered / .machine_detected / .failed | Voice Proactive Outreach call state changes (can arrive out of order) |
Full payloads: references/overview.md and Ada's webhook docs.
Delivery Semantics
- Return a
2xxwithin 15 seconds. Enqueue the event and process it asynchronously. - Retries use exponential backoff (immediate, 5s, 5m, 30m, 2h, 5h, 10h). An endpoint that fails for a week is disabled.
- Resend single messages or recover failed messages from the endpoint page.
- Deliveries come from Svix source IPs (US list for
*.ada.support, EU list for*.ada-eu.support).
Environment Variables
ADA_WEBHOOK_SECRET=whsec_xxxxx # endpoint's signing secret; handlers fail closed (500) without it
Get it from Config > PLATFORM > Webhooks → your endpoint → Signing Secret, or with GET /api/v2/webhooks/{id}/secret/.
Local Development
# Express / Next.js (use 8000 for FastAPI). No install or account required.
npx hookdeck-cli listen 3000 ada --path /webhooks/ada
Add the printed URL with Add Endpoint in Config > PLATFORM > Webhooks, choose event types, and start a conversation with your AI Agent.
Reference Materials
- references/overview.md - Event catalog, payload fields, retries
- references/setup.md - Dashboard and API endpoint setup, signing secret, rotation, channel filtering
- references/verification.md - Library and manual verification, gotchas, debugging