{"id":"6c72af2d-74b9-4b2e-8d08-4017d418ea0d","shortId":"DfZ9JK","kind":"skill","title":"webhook-handler-patterns","tagline":"Best practices for webhook handlers. Use when implementing the handler sequence (verify first, parse second, handle idempotently), idempotency, error handling, retry logic, or framework-specific issues with Express, Next.js, or FastAPI.","description":"# Webhook Handler Patterns\n\n## When to Use This Skill\n\n- Following the correct webhook handler order (verify → parse → handle idempotently)\n- Implementing idempotent webhook handlers\n- Handling errors and configuring retry behavior\n- Understanding framework-specific gotchas (raw body, middleware order)\n- Building production-ready webhook infrastructure\n\n## Resources\n\n### Handler Sequence\n\n- [references/handler-sequence.md](references/handler-sequence.md) - Verify first, parse second, handle idempotently third\n\n### Best Practices\n\n- [references/idempotency.md](references/idempotency.md) - Prevent duplicate processing\n- [references/error-handling.md](references/error-handling.md) - Return codes, logging, dead letter queues\n- [references/retry-logic.md](references/retry-logic.md) - Provider retry schedules, backoff patterns\n\n### Framework Guides\n\n- [references/frameworks/express.md](references/frameworks/express.md) - Express.js patterns and gotchas\n- [references/frameworks/nextjs.md](references/frameworks/nextjs.md) - Next.js App Router patterns\n- [references/frameworks/fastapi.md](references/frameworks/fastapi.md) - FastAPI/Python patterns\n\n## Quick Reference\n\n### Handler Sequence\n\n1. **Verify signature first** — Use raw body; reject invalid requests with 4xx.\n2. **Parse payload second** — After verification, parse or construct the event.\n3. **Handle idempotently third** — Check event ID, then process; return 2xx for duplicates.\n\nSee [references/handler-sequence.md](references/handler-sequence.md) for details and links to provider verification and idempotency patterns.\n\n### Response Codes\n\n| Code | Meaning | Provider Behavior |\n|------|---------|-------------------|\n| `2xx` | Success | No retry |\n| `4xx` | Client error | Usually no retry (except 429) |\n| `5xx` | Server error | Retry with backoff |\n| `429` | Rate limited | Retry after delay |\n\n### Idempotency Checklist\n\n1. Extract unique event ID from payload\n2. Check if event was already processed\n3. Process event within transaction\n4. Store event ID after successful processing\n5. Return success for duplicate events\n\n## Related Skills\n\n- [stripe-webhooks](https://github.com/hookdeck/webhook-skills/tree/main/skills/stripe-webhooks) - Stripe payment webhook handling\n- [shopify-webhooks](https://github.com/hookdeck/webhook-skills/tree/main/skills/shopify-webhooks) - Shopify e-commerce webhook handling\n- [github-webhooks](https://github.com/hookdeck/webhook-skills/tree/main/skills/github-webhooks) - GitHub repository webhook handling\n- [resend-webhooks](https://github.com/hookdeck/webhook-skills/tree/main/skills/resend-webhooks) - Resend email webhook handling\n- [chargebee-webhooks](https://github.com/hookdeck/webhook-skills/tree/main/skills/chargebee-webhooks) - Chargebee billing webhook handling\n- [clerk-webhooks](https://github.com/hookdeck/webhook-skills/tree/main/skills/clerk-webhooks) - Clerk auth webhook handling\n- [elevenlabs-webhooks](https://github.com/hookdeck/webhook-skills/tree/main/skills/elevenlabs-webhooks) - ElevenLabs webhook handling\n- [openai-webhooks](https://github.com/hookdeck/webhook-skills/tree/main/skills/openai-webhooks) - OpenAI webhook handling\n- [paddle-webhooks](https://github.com/hookdeck/webhook-skills/tree/main/skills/paddle-webhooks) - Paddle billing webhook handling\n- [hookdeck-event-gateway](https://github.com/hookdeck/webhook-skills/tree/main/skills/hookdeck-event-gateway) - Webhook infrastructure that replaces your queue — guaranteed delivery, automatic retries, replay, rate limiting, and observability for your webhook handlers","tags":["webhook","handler","patterns","skills","hookdeck","agent-skills","ai-coding","api-integrations","event-driven","github-webhooks","llm-tools","shopify-webhooks"],"capabilities":["skill","source-hookdeck","skill-webhook-handler-patterns","topic-agent-skills","topic-ai-coding","topic-api-integrations","topic-event-driven","topic-github-webhooks","topic-llm-tools","topic-shopify-webhooks","topic-stripe-webhooks","topic-webhook-security","topic-webhook-signatures","topic-webhooks"],"categories":["webhook-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/hookdeck/webhook-skills/webhook-handler-patterns","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add hookdeck/webhook-skills","source_repo":"https://github.com/hookdeck/webhook-skills","install_from":"skills.sh"}},"qualityScore":"0.484","qualityRationale":"deterministic score 0.48 from registry signals: · indexed on github topic:agent-skills · 69 github stars · SKILL.md body (3,576 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-02T06:55:48.090Z","embedding":null,"createdAt":"2026-04-18T22:14:04.882Z","updatedAt":"2026-05-02T06:55:48.090Z","lastSeenAt":"2026-05-02T06:55:48.090Z","tsv":"'/hookdeck/webhook-skills/tree/main/skills/chargebee-webhooks)':298 '/hookdeck/webhook-skills/tree/main/skills/clerk-webhooks)':308 '/hookdeck/webhook-skills/tree/main/skills/elevenlabs-webhooks)':318 '/hookdeck/webhook-skills/tree/main/skills/github-webhooks)':278 '/hookdeck/webhook-skills/tree/main/skills/hookdeck-event-gateway)':347 '/hookdeck/webhook-skills/tree/main/skills/openai-webhooks)':327 '/hookdeck/webhook-skills/tree/main/skills/paddle-webhooks)':336 '/hookdeck/webhook-skills/tree/main/skills/resend-webhooks)':288 '/hookdeck/webhook-skills/tree/main/skills/shopify-webhooks)':266 '/hookdeck/webhook-skills/tree/main/skills/stripe-webhooks)':256 '1':136,217 '2':148,224 '2xx':169,191 '3':159,231 '4':236 '429':202,209 '4xx':147,195 '5':243 '5xx':203 'alreadi':229 'app':125 'auth':310 'automat':356 'backoff':112,208 'behavior':64,190 'best':5,92 'bill':300,338 'bodi':71,142 'build':74 'chargebe':294,299 'chargebee-webhook':293 'check':163,225 'checklist':216 'clerk':304,309 'clerk-webhook':303 'client':196 'code':102,186,187 'commerc':270 'configur':62 'construct':156 'correct':47 'dead':104 'delay':214 'deliveri':355 'detail':176 'duplic':97,171,247 'e':269 'e-commerc':268 'elevenlab':314,319 'elevenlabs-webhook':313 'email':290 'error':23,60,197,205 'event':158,164,220,227,233,238,248,343 'except':201 'express':33 'express.js':118 'extract':218 'fastapi':36 'fastapi/python':130 'first':17,86,139 'follow':45 'framework':29,67,114 'framework-specif':28,66 'gateway':344 'github':274,279 'github-webhook':273 'github.com':255,265,277,287,297,307,317,326,335,346 'github.com/hookdeck/webhook-skills/tree/main/skills/chargebee-webhooks)':296 'github.com/hookdeck/webhook-skills/tree/main/skills/clerk-webhooks)':306 'github.com/hookdeck/webhook-skills/tree/main/skills/elevenlabs-webhooks)':316 'github.com/hookdeck/webhook-skills/tree/main/skills/github-webhooks)':276 'github.com/hookdeck/webhook-skills/tree/main/skills/hookdeck-event-gateway)':345 'github.com/hookdeck/webhook-skills/tree/main/skills/openai-webhooks)':325 'github.com/hookdeck/webhook-skills/tree/main/skills/paddle-webhooks)':334 'github.com/hookdeck/webhook-skills/tree/main/skills/resend-webhooks)':286 'github.com/hookdeck/webhook-skills/tree/main/skills/shopify-webhooks)':264 'github.com/hookdeck/webhook-skills/tree/main/skills/stripe-webhooks)':254 'gotcha':69,121 'guarante':354 'guid':115 'handl':20,24,53,59,89,160,260,272,282,292,302,312,321,330,340 'handler':3,9,14,38,49,58,81,134,366 'hookdeck':342 'hookdeck-event-gateway':341 'id':165,221,239 'idempot':21,22,54,56,90,161,183,215 'implement':12,55 'infrastructur':79,349 'invalid':144 'issu':31 'letter':105 'limit':211,360 'link':178 'log':103 'logic':26 'mean':188 'middlewar':72 'next.js':34,124 'observ':362 'openai':323,328 'openai-webhook':322 'order':50,73 'paddl':332,337 'paddle-webhook':331 'pars':18,52,87,149,154 'pattern':4,39,113,119,127,131,184 'payload':150,223 'payment':258 'practic':6,93 'prevent':96 'process':98,167,230,232,242 'product':76 'production-readi':75 'provid':109,180,189 'queue':106,353 'quick':132 'rate':210,359 'raw':70,141 'readi':77 'refer':133 'references/error-handling.md':99,100 'references/frameworks/express.md':116,117 'references/frameworks/fastapi.md':128,129 'references/frameworks/nextjs.md':122,123 'references/handler-sequence.md':83,84,173,174 'references/idempotency.md':94,95 'references/retry-logic.md':107,108 'reject':143 'relat':249 'replac':351 'replay':358 'repositori':280 'request':145 'resend':284,289 'resend-webhook':283 'resourc':80 'respons':185 'retri':25,63,110,194,200,206,212,357 'return':101,168,244 'router':126 'schedul':111 'second':19,88,151 'see':172 'sequenc':15,82,135 'server':204 'shopifi':262,267 'shopify-webhook':261 'signatur':138 'skill':44,250 'skill-webhook-handler-patterns' 'source-hookdeck' 'specif':30,68 'store':237 'stripe':252,257 'stripe-webhook':251 'success':192,241,245 'third':91,162 'topic-agent-skills' 'topic-ai-coding' 'topic-api-integrations' 'topic-event-driven' 'topic-github-webhooks' 'topic-llm-tools' 'topic-shopify-webhooks' 'topic-stripe-webhooks' 'topic-webhook-security' 'topic-webhook-signatures' 'topic-webhooks' 'transact':235 'understand':65 'uniqu':219 'use':10,42,140 'usual':198 'verif':153,181 'verifi':16,51,85,137 'webhook':2,8,37,48,57,78,253,259,263,271,275,281,285,291,295,301,305,311,315,320,324,329,333,339,348,365 'webhook-handler-pattern':1 'within':234","prices":[{"id":"38303665-3036-456c-ad19-61e3f141a20a","listingId":"6c72af2d-74b9-4b2e-8d08-4017d418ea0d","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"hookdeck","category":"webhook-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T22:14:04.882Z"}],"sources":[{"listingId":"6c72af2d-74b9-4b2e-8d08-4017d418ea0d","source":"github","sourceId":"hookdeck/webhook-skills/webhook-handler-patterns","sourceUrl":"https://github.com/hookdeck/webhook-skills/tree/main/skills/webhook-handler-patterns","isPrimary":false,"firstSeenAt":"2026-04-18T22:14:04.882Z","lastSeenAt":"2026-05-02T06:55:48.090Z"}],"details":{"listingId":"6c72af2d-74b9-4b2e-8d08-4017d418ea0d","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"hookdeck","slug":"webhook-handler-patterns","github":{"repo":"hookdeck/webhook-skills","stars":69,"topics":["agent-skills","ai-coding","api-integrations","event-driven","github-webhooks","llm-tools","shopify-webhooks","stripe-webhooks","webhook-security","webhook-signatures","webhooks"],"license":"mit","html_url":"https://github.com/hookdeck/webhook-skills","pushed_at":"2026-02-25T14:00:40Z","description":"Webhook integration skills for AI coding agents (Claude Code, Cursor, Copilot). Step-by-step guidance for setting up webhook receivers, signature verification, and event handling for Stripe, Shopify, GitHub, and more. Built on the Agent Skills specification.","skill_md_sha":"4b39328dcecf29499d35c7bb174cb82f9887a3f9","skill_md_path":"skills/webhook-handler-patterns/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/hookdeck/webhook-skills/tree/main/skills/webhook-handler-patterns"},"layout":"multi","source":"github","category":"webhook-skills","frontmatter":{"name":"webhook-handler-patterns","license":"MIT","description":"Best practices for webhook handlers. Use when implementing the handler sequence (verify first, parse second, handle idempotently), idempotency, error handling, retry logic, or framework-specific issues with Express, Next.js, or FastAPI."},"skills_sh_url":"https://skills.sh/hookdeck/webhook-skills/webhook-handler-patterns"},"updatedAt":"2026-05-02T06:55:48.090Z"}}