Production Checklist

Before deploying your webhook handler to production, ensure you've covered all these critical items.

Security

✅ HTTPS Only

  • Webhook URL uses https://
  • SSL certificate is valid
  • HTTP requests are redirected to HTTPS

✅ Signature Verification

  • Implement HMAC signature verification
  • Use constant-time comparison
  • Reject requests with invalid signatures
  • Rotate secrets if compromised
if (!verifySignature(req)) {
  return res.status(401).send('Invalid signature');
}

✅ Timestamp Validation

  • Reject old requests (> 5 minutes)
  • Prevent replay attacks
const timestamp = req.headers['x-webhook-timestamp'];
const now = Math.floor(Date.now() / 1000);

if (Math.abs(now - parseInt(timestamp)) > 300) {
  return res.status(401).send('Timestamp too old');
}

Reliability

✅ Quick Response

  • Return 2xx within 5 seconds
  • Process asynchronously using queues
  • Handle errors without failing the request
app.post('/webhooks/sent', (req, res) => {
  // Acknowledge immediately
  res.sendStatus(200);

  // Process in background — include X-Webhook-ID for idempotency
  queue.add('webhook', {
    eventId: req.headers['x-webhook-id'],
    ...req.body,
  });
});

✅ Idempotency

  • Deduplicate events by event ID
  • Store processed event IDs
  • Handle out-of-order events
  • Use database transactions

See Handling Retries for implementation.

✅ Retry Handling

  • Expect duplicate deliveries
  • Handle events at least once
  • Implement exponential backoff for your retries

Monitoring

✅ Logging

  • Log all webhook events
  • Include event ID, timestamp, status
  • Use structured logging (JSON)
  • Set appropriate log levels
logger.info('Webhook received', {
  eventId: req.headers['x-webhook-id'],
  eventType: req.body.field,
  timestamp: new Date().toISOString()
});

✅ Alerting

  • Alert on high error rates
  • Monitor webhook delivery failures
  • Set up PagerDuty/Opsgenie for critical issues
if (errorRate > 0.05) { // 5% error rate
  await alertTeam('High webhook error rate', { errorRate });
}

✅ Metrics

Track:

  • Webhook events received (counter)
  • Processing duration (histogram)
  • Failed events (counter)
  • Queue depth (gauge)

Error Handling

✅ Graceful Degradation

  • Handle partial failures
  • Continue processing other events
  • Don't fail the entire batch
for (const event of events) {
  try {
    await processEvent(event);
  } catch (error) {
    logger.error('Event processing failed', { event, error });
    // Continue with next event
  }
}

✅ Dead Letter Queue

  • Failed events go to DLQ
  • Manual review process
  • Retry from DLQ capability

Scalability

✅ Queue-Based Processing

  • Use Redis/RabbitMQ/SQS
  • Multiple worker processes
  • Horizontal scaling ready
const worker = new Worker('webhooks', processor, {
  connection: redisConnection,
  concurrency: 10
});

✅ Rate Limiting

  • Protect downstream services
  • Implement backoff
  • Queue events if overloaded

Testing

✅ Local Testing

  • Test with ngrok/localtunnel
  • Verify signature verification
  • Test retry handling

See Local Development.

✅ Load Testing

  • Test with high event volume
  • Verify queue doesn't overflow
  • Check response times

✅ Failure Testing

  • Test with invalid signatures
  • Test with malformed payloads
  • Test database failure scenarios

Infrastructure

✅ High Availability

  • Multiple server instances
  • Load balancer configured
  • Database replicas
  • Redis cluster (if using)

✅ Backups

  • Database backups
  • Configuration backups
  • Tested restore procedures

Pre-Launch Verification

Run through this final checklist:

  • Webhook URL returns 200 quickly (< 1s response time)
  • Signature verification rejects invalid signatures
  • Duplicate events are handled correctly
  • Logs are flowing to central logging
  • Alerts are configured and tested
  • Queue workers are running
  • Database connections are pooled
  • SSL certificate is valid
  • Rate limits are configured
  • Runbook is documented

Dashboard Configuration

Verify in Sent Dashboard:

  • Webhook URL is correct
  • Event types are selected
  • Secret is secure
  • Test webhook delivery succeeds

Runbook Template

Create a runbook for your team:

# Webhook Runbook

## High Error Rate Alert
1. Check webhook logs in dashboard
2. Verify endpoint is responding
3. Check application logs
4. If needed, temporarily disable webhook

## Missed Events
1. Check webhook delivery logs
2. Verify idempotency handling
3. Manual replay if needed

## Secret Rotation
1. Generate new secret in dashboard
2. Update application config
3. Deploy new config
4. Test webhook
5. Remove old secret

Ready to go live? After completing this checklist, enable your webhook in the Sent Dashboard and monitor closely for the first 24 hours.


On this page