| name | webhook-patterns |
| description | Webhook design and handling — signature verification, retry logic, idempotency, event routing, testing. Use when working with webhook patterns. |
| domain | integrations |
| author | oyi77 |
| license | Apache-2.0 |
| subdomain | integrations |
| tags | ["api","integrations","patterns","testing","third-party","webhook"] |
| version | 1.0.0 |
Overview
Design, implement, and consume webhooks — secure signature verification, idempotent processing, retry handling, event routing, and testing strategies.
Capabilities
- Webhook endpoint design (Express, Fastify, serverless)
- HMAC signature verification (Stripe, GitHub, Shopify)
- Idempotent event processing
- Retry and dead letter handling
- Event routing and filtering
- Testing with ngrok and webhook.site
When to Use
Trigger phrases:
-
"webhook patterns"
-
"Webhook design and handling — signature verification, retry logic, idempotency, "
-
Receiving real-time events from SaaS platforms
-
Building event-driven integrations between systems
-
Processing payment confirmations (Stripe, Paddle)
-
Handling CI/CD events (GitHub, GitLab)
-
Building notification and alerting systems
When NOT to Use
- Task is outside your authorization scope
- You need to implement controls (use implementing-* skills)
- Task is about analysis, not action (use analyzing-* skills)
- You don't have access to target systems
- Task requires compliance expertise (consult professionals)
- Task is about defense, not offense (use defensive skills)
Pseudo Code
def execute(input_data):
if not input_data:
raise ValueError("Input data is required")
result = process(input_data)
validate_output(result)
return result
Express Webhook Endpoint
const express = require("express");
const crypto = require("crypto");
const app = express();
app.post("/webhooks/stripe", express.raw({ type: "application/json" }), (req, res) => {
const sig = req.headers["stripe-signature"];
const secret = process.env.STRIPE_WEBHOOK_SECRET;
const expected = crypto.createHmac("sha256", secret).update(req.body).digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
return res.status(401).send("Invalid signature");
}
const event = JSON.parse(req.body);
if (processedEvents.has(event.id)) {
return res.().();
}
(event.) {
:
(event..);
;
:
(event..);
;
}
processedEvents.(event.);
res.().();
});
GitHub Webhook Verification
function verifyGitHub(req, res, next) {
const signature = req.headers["x-hub-signature-256"];
const secret = process.env.GITHUB_WEBHOOK_SECRET;
const hmac = crypto.createHmac("sha256", secret);
const digest = "sha256=" + hmac.update(req.rawBody).digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(digest))) {
return res.status(401).send("Invalid signature");
}
next();
}
app.post("/webhooks/github", verifyGitHub, (req, res) => {
const event = req.headers["x-github-event"];
const payload = req.body;
if (event === "push") {
handlePush(payload);
} else if (event === "pull_request") {
handlePR(payload);
}
res.status(200).send();
});
Retry Handler (Consumer Side)
async function processWithRetry(event, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
await processEvent(event);
return;
} catch (err) {
if (i === maxRetries - 1) {
await deadLetterQueue.publish(event);
console.error(`Failed after ${maxRetries} retries:`, err);
}
await sleep(Math.pow(2, i) * 1000);
}
}
}
Testing with ngrok
ngrok http 3000
Common Patterns
- Signature Verification: Always verify HMAC before processing
- Idempotency: Track processed event IDs to avoid duplicates
- Async Processing: Return 200 immediately, process in background
- Dead Letter Queue: Store failed events for manual review
- Event Routing: Route by event type to dedicated handlers
- Webhook Testing: Use ngrok/webhook.site for local development
How to Use
- Invoke the skill when relevant domain keywords appear in the request
- Provide required inputs as specified in the skill definition
- Review the output for correctness before delivering to the user
- Combine with related skills for complex multi-step workflows
Verification
After completing this skill, confirm:
Process
- Analyze the task requirements
- Apply domain expertise
- Verify output quality
Anti-Rationalization Table
| Rationalization | Reality |
|---|
| "I will handle auth later" | Retrofitting auth is 10x harder. Build it from day one. |
| "APIs do not change" | APIs change. Version your integrations and handle deprecations. |
| "Webhooks are optional" | Without webhooks, you miss real-time events. They are essential. |