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.message or v1.conversation.ended?
  • Why is my Ada svix-signature verification failing?
  • How do I dedupe Ada webhook retries when the payload has no event ID?

Verification (core)

HeaderValue
svix-idUnique message ID, the same on every retry
svix-timestampUnix seconds of this delivery attempt
svix-signaturev1,<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

EventFired when
v1.conversation.createdA new conversation is created for a supported channel
v1.conversation.messageA message is added (author.role: end_user, ai_agent, human_agent)
v1.conversation.endedA conversation ends (end endpoint called or Voice call disconnects)
v1.conversation.handoff.endedA handoff to a human agent integration ends
v1.end_user.created / v1.end_user.updatedAn end user is created / a profile value changes
v1.audit_log.emittedA configuration change is recorded in the Audit log
v1.proactive_call.queued / .initiated / .answered / .machine_detected / .failedVoice Proactive Outreach call state changes (can arrive out of order)

Full payloads: references/overview.md and Ada's webhook docs.

Delivery Semantics

  • Return a 2xx within 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


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Oct 28, 2026

View on GitHub →