Skip to main content

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
Always verify webhook signatures to ensure requests are genuinely from AutoSend.

How AutoSend Signs Webhooks

Every webhook request from AutoSend includes an X-Webhook-Signature header containing an HMAC-SHA256 signature.

Signature Generation

AutoSend generates the signature using this process:
  1. Format the webhook payload with the event type, timestamp, and event data
  2. Convert the payload to JSON string (the raw request body)
  3. Compute HMAC-SHA256 using your webhook secret as the key
  4. Convert to hexadecimal format
  5. Add as header: X-Webhook-Signature: <signature>

Webhook Request Headers

Every webhook request includes these headers:
string
required
HMAC-SHA256 signature of the request body in hexadecimal formatExample: "a1b2c3d4e5f6..."
string
required
The event typeExample: "email.opened"
string
required
Unique delivery identifier (job ID from the queue system)Example: "delivery-123..."
string
required
Unix timestamp in milliseconds when the webhook was sentExample: "1699790400000"
string
required
Always application/jsonExample: "application/json"
string
AutoSend user agent (if set)Example: "AutoSend-Webhooks/1.0"

Steps to Verify Signatures

1

Extract the signature from the X-Webhook-Signature header

2

Get the raw request body as a string (before parsing)

3

Compute the expected signature using your webhook secret

4

Compare signatures using a constant-time comparison function


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:
2

Click on the webhook you want to manage

3

Click the Reveal Secret button

4

Copy the secret and store it securely in your environment variables

Store your webhook secret securely. Never commit it to version control or expose it in client-side code.

Complete Production Example

Here’s a complete, production-ready webhook endpoint with signature verification, timestamp validation, and error handling:

Security Best Practices

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.
Never hardcode webhook secrets in your code:
Store secrets in:
  • Environment variables (.env files for local development)
  • Secure secret management services (AWS Secrets Manager, HashiCorp Vault, etc.)
  • Encrypted configuration files
Never:
  • 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
Compute signatures using the raw, unparsed request body. Do not re-stringify the parsed JSON:
JSON stringification is not deterministic. The order of object keys may differ, causing signature verification to fail.
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().
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.
Webhook requests have a 10-second timeout. Always respond within this time:
If your endpoint doesn’t respond within 10 seconds, AutoSend will consider the delivery failed and retry up to 3 times.
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.
Regularly rotate your webhook secrets for enhanced security:
1

Create a new webhook with the same events and URL

2

Update your application to support both old and new secrets temporarily

3

Verify the new webhook is working correctly

4

Delete the old webhook

5

Remove the old secret from your application


Webhook Payload Structure

AutoSend sends webhook payloads in this format:
string
required
The event type (e.g., "email.opened", "contact.created")
string
required
ISO 8601 timestamp when the event occurred
object
required
Event-specific data (varies by event type)

Troubleshooting

Symptoms: All webhook requests return 401 UnauthorizedCommon Causes:
  1. Using the wrong secret
  2. Body parsing issues
  3. String encoding issues
  4. Comparing wrong values
  5. Secret contains whitespace
Symptoms: Requests fail with “Invalid timestamp” errorCommon Causes:
  1. Wrong time unit - Timestamp is in milliseconds, not seconds
  2. Clock skew - Server time is off
  3. Timezone issues
Test your signature verification without waiting for real webhooks:
Symptoms: No webhook requests arriving at your endpointTroubleshooting Steps:
  1. 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)
  2. Verify URL is accessible
  3. Check delivery logs
    • Click on your webhook in AutoSend
    • View the “Delivery Logs” tab
    • Look for error messages or status codes
  4. 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

Introduction

Getting started with AutoSend webhooks

Delivery Logs

View webhook delivery history and debug issues