Skip to content

feat: add vapi-webhooks skill - #178

Draft
garethx wants to merge 1 commit into
hookdeck:mainfrom
garethx:feat/vapi-webhooks
Draft

feat: add vapi-webhooks skill#178
garethx wants to merge 1 commit into
hookdeck:mainfrom
garethx:feat/vapi-webhooks

Conversation

@garethx

@garethx garethx commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a webhook skill for Vapi (voice-AI agent platform — the "Server URL"). Collision check clean: no prior vapi-webhooks skill or providers.yaml entry.

Authored from Vapi's canonical docs (server-url, events, server-authentication). This one needed care rather than a stock HMAC template — Vapi has no fixed signature scheme, so the skill is written to avoid fabricating a construction.

Why this skill is unusual

  • Auth is opt-in and per-endpoint. A Server URL has no auth until you attach a Custom Credential. Four types exist: Bearer Token, legacy X-Vapi-Secret, OAuth 2.0, and a fully-configurable HMAC.
  • Primary path = shared secret (Authorization: Bearer <token> or legacy X-Vapi-Secret) — a literal, timing-safe compare, not an HMAC. The examples implement this and read whichever header is present.
  • HMAC is documented generically, not hardcoded. Vapi lets the customer choose the algorithm, header name, optional timestamp header, and payload format, and pins no defaults — so references/verification.md refuses to assert one. OAuth 2.0 is covered as the token-validation path.
  • No fabricated helper. A verifyVapiSignature name in a CLI tutorial is an unimplemented placeholder — the skill explicitly does not use it. No official SDK verify helper exists; no documented source-IP allowlist.
  • Nested envelope. The event type is at message.type, not top-level (a CLI tutorial shows a flatter shape with names like call-started — that's informal example code, not the wire format; the skill follows /server-url/events).
  • Bidirectional request/response protocol. Four message types require a JSON response body, which the handlers implement: assistant-request (hard ~7.5s timeout), tool-calls, transfer-destination-request, knowledge-base-request. All other types get a bare 200.

Tests

  • Express: 19 passed
  • Next.js: 14 passed
  • FastAPI: 18 passed
  • validate-provider.sh vapi-webhooks: passed

Auth tests cover both the Bearer and legacy X-Vapi-Secret headers, wrong/missing secret → 401, and the required response bodies for all four request/response types.

Notes for the reviewer

  • Not live-verified. Authored from docs, not a captured delivery (no Vapi test account in this run). Residual unknowns — exact HMAC construction (undocumented by design), precise response shapes, and the ~7.5s budget — are recorded in skills/vapi-webhooks/TODO.md for a future live pass.

Left as a draft pending sign-off.

🤖 Generated with Claude Code

Vapi voice-AI agent platform ("Server URL" webhooks). Authored from the
canonical docs (server-url, server-url/events, server-url/server-authentication)
because Vapi has no fixed signature scheme and needed careful, non-fabricating
treatment.

Key decisions:
- Auth is opt-in and per-endpoint. The skill's primary, fully-specified path is
  the shared secret (Authorization: Bearer <token> or the legacy X-Vapi-Secret
  header) — a literal, timing-safe compare, not an HMAC. OAuth 2.0 and a
  fully-configurable HMAC are documented as secondary options WITHOUT asserting a
  fixed header/algorithm/signed-string, since Vapi pins no defaults.
- The event type is nested at message.type (per /server-url/events), not the
  flatter top-level shape shown in an informal CLI tutorial. The tutorial's
  `verifyVapiSignature` is a placeholder, not a real export — not used.
- Handlers implement the request/response protocol: assistant-request,
  tool-calls, transfer-destination-request, and knowledge-base-request return the
  required JSON body; all other message types get a bare 200.

Tests: Express 19, Next.js 14, FastAPI 18 pass; validate-provider.sh passes.
Residual unknowns (no live account; HMAC construction undocumented) recorded in
skills/vapi-webhooks/TODO.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant