Why Verify Webhooks?
Security is critical. Anyone can send a POST request to your webhook endpoint. Without verification, malicious actors could:- Send fake events to corrupt your data
- Trigger unwanted actions in your application
- Cause your system to process fraudulent information
- Launch denial-of-service attacks
How AutoSend Signs Webhooks
Every webhook request from AutoSend includes anX-Webhook-Signature header containing an HMAC-SHA256 signature.
Signature Generation
AutoSend generates the signature using this process:- Format the webhook payload with the event type, timestamp, and event data
- Convert the payload to JSON string (the raw request body)
- Compute HMAC-SHA256 using your webhook secret as the key
- Convert to hexadecimal format
- Add as header:
X-Webhook-Signature: <signature>
Webhook Request Headers
Every webhook request includes these headers:HMAC-SHA256 signature of the request body in hexadecimal formatExample:
"a1b2c3d4e5f6..."The event typeExample:
"email.opened"Unique delivery identifier (job ID from the queue system)Example:
"delivery-123..."Unix timestamp in milliseconds when the webhook was sentExample:
"1699790400000"Always
application/jsonExample: "application/json"AutoSend user agent (if set)Example:
"AutoSend-Webhooks/1.0"Steps to Verify Signatures
Retrieving Your Webhook Secret
Your webhook secret is shown only once when you create the webhook. If you’ve lost it, you can retrieve it:Complete Production Example
Here’s a complete, production-ready webhook endpoint with signature verification, timestamp validation, and error handling:Security Best Practices
Always Use Constant-Time Comparison
Always Use Constant-Time Comparison
Never use
=== or == to compare signatures. Use constant-time comparison functions to prevent timing attacks:The
crypto.timingSafeEqual() function throws an error if the buffer lengths don’t match. Always wrap it in a try-catch block.Store Secrets Securely
Store Secrets Securely
Never hardcode webhook secrets in your code:Store secrets in:
- Environment variables (
.envfiles for local development) - Secure secret management services (AWS Secrets Manager, HashiCorp Vault, etc.)
- Encrypted configuration files
- Commit secrets to version control
- Include secrets in client-side code
- Share secrets in logs or error messages
- Use the same secret across multiple environments
Use the Raw Request Body
Use the Raw Request Body
Compute signatures using the raw, unparsed request body. Do not re-stringify the parsed JSON:
Validate the Timestamp
Validate the Timestamp
Validate the
X-Webhook-Timestamp header to reject old or replayed requests:The timestamp is in milliseconds (not seconds). AutoSend sends timestamps as
Date.now().toString().Use HTTPS for Production
Use HTTPS for Production
Always use HTTPS for your webhook endpoints in production:HTTPS ensures:
- Requests are encrypted in transit
- Man-in-the-middle attacks are prevented
- Webhook data remains confidential
- Your webhook secret is protected
AutoSend does not enforce HTTPS for webhook URLs, but it is strongly recommended for production use.
Respond Quickly (Under 10 Seconds)
Respond Quickly (Under 10 Seconds)
Webhook requests have a 10-second timeout. Always respond within this time:
Handle Webhook Retries Idempotently
Handle Webhook Retries Idempotently
AutoSend retries failed deliveries up to 3 times. Make your webhook handler idempotent:
Use the
X-Webhook-Delivery-Id header to track which deliveries you’ve already processed.Rotate Secrets Periodically
Rotate Secrets Periodically
Webhook Payload Structure
AutoSend sends webhook payloads in this format:The event type (e.g.,
"email.opened", "contact.created")ISO 8601 timestamp when the event occurred
Event-specific data (varies by event type)
Troubleshooting
Signature Verification Always Fails
Signature Verification Always Fails
Symptoms: All webhook requests return 401 UnauthorizedCommon Causes:
-
Using the wrong secret
-
Body parsing issues
-
String encoding issues
-
Comparing wrong values
-
Secret contains whitespace
Timestamp Validation Fails
Timestamp Validation Fails
Symptoms: Requests fail with “Invalid timestamp” errorCommon Causes:
-
Wrong time unit - Timestamp is in milliseconds, not seconds
-
Clock skew - Server time is off
-
Timezone issues
Testing Signature Verification Locally
Testing Signature Verification Locally
Test your signature verification without waiting for real webhooks:
Webhooks Not Being Received
Webhooks Not Being Received
Symptoms: No webhook requests arriving at your endpointTroubleshooting Steps:
-
Check webhook is active
- Navigate to Webhooks in AutoSend
- Verify webhook status is “Active”
- Check if failure count is high (auto-disabled after 5 failures)
-
Verify URL is accessible
-
Check delivery logs
- Click on your webhook in AutoSend
- View the “Delivery Logs” tab
- Look for error messages or status codes
-
Test with resend
- Create a test event
- Use the “Resend” feature to manually trigger delivery
- Check your server logs
Next Steps
Event Types
Learn about all available webhook events and their payloads
Retries and Replays
Understand how AutoSend handles failed deliveries
Best Practices
Production deployment guidelines and optimization tips
Manage Webhooks
Configure and monitor your webhooks in AutoSend
Related Resources
Introduction
Getting started with AutoSend webhooks
Delivery Logs
View webhook delivery history and debug issues