Why Webhook Security Matters
Without signature verification, anyone who discovers your webhook URL could send fake events to your application, potentially causing:- ❌ Fake completion events triggering incorrect business logic
- ❌ Data corruption from processing invalid events
- ❌ Unauthorized access to your application
- ❌ Security vulnerabilities
How Signature Verification Works
Magic Hour signs every webhook using HMAC-SHA256 with your webhook secret:- Magic Hour creates a signed payload:
{timestamp}.{json_payload} - Magic Hour computes HMAC-SHA256 signature using your webhook secret
- Magic Hour sends the webhook with signature and timestamp in headers
- Your app recreates the same signed payload
- Your app computes the same HMAC-SHA256 signature
- Your app compares signatures - if they match, the webhook is authentic
Security Headers
Every webhook includes two security headers to help you verify authenticity:magic-hour-event-signature
The HMAC-SHA256 signature computed using your webhook secret and the signed payload.
Example:
magic-hour-event-timestamp
Unix timestamp (seconds since epoch) when Magic Hour sent the webhook.
Example:
- Prevents replay attacks by rejecting old webhooks
- Recommended tolerance: Accept webhooks within 5 minutes of current time
- If timestamp is too old or too far in the future, reject the webhook
Header Case: HTTP headers are case-insensitive.
Magic-Hour-Event-Signature and
magic-hour-event-signature are equivalent.Optional but Recommended: Signature verification is not required to receive webhooks, but it’s
strongly recommended for production to ensure authenticity.
1
Extract Headers and Payload
Get the signature, timestamp, and raw JSON payload from the incoming request:
2
Extract the headers and payload
What to do: Get three pieces of information from the incoming webhook request:
- Signature header:
magic-hour-event-signature - Timestamp header:
magic-hour-event-timestamp - Raw JSON body: The entire request body as a string (not parsed yet)
3
Create the signed payload
What to do: Combine the timestamp and raw payload into a single string for signature computation.Format: Code example:Why: The signed payload is what Magic Hour used to create the signature. You need to recreate it exactly the same way.
{timestamp}.{raw_json_payload}Example signed payload:4
Compute your signature
What to do: Generate an HMAC-SHA256 hash using:
- Key: Your webhook secret (from Magic Hour Developer Hub)
- Message: The signed payload you just created
5
Verify the signature
What to do: Compare your computed signature with the signature Magic Hour sent in the header.Important: Use a constant-time comparison to prevent timing attacks:Why constant-time comparison: Regular string comparison (
==) can leak timing information that attackers could exploit. hmac.compare_digest() prevents this.6
Verify the timestamp
What to do: Check that the webhook was sent recently (within 5 minutes is recommended).Why: Prevents replay attacks where someone could resend an old valid webhook.Adjust tolerance: You can adjust the 300-second (5-minute) window based on your needs, but keep it reasonable for security.
Complete Secure Handler Implementation
Testing Your Secure Handler
Test signature verification with a sample webhook:Best Practices
1. Environment Variables
Store your webhook secret securely:2. Error Handling
Handle verification failures gracefully:3. Logging
Log security events for monitoring:4. Rate Limiting
Protect against abuse:Troubleshooting
Common Issues
“Invalid signature” errors:- ✅ Ensure you’re using the raw JSON payload, not parsed/re-stringified
- ✅ Check that your webhook secret is correct
- ✅ Verify timestamp format (Unix seconds, not milliseconds)
- ✅ Make sure you’re concatenating
timestamp.payloadcorrectly
- ✅ Check server clock synchronization
- ✅ Increase tolerance window if needed (but keep it reasonable)
- ✅ Ensure timestamp is in seconds, not milliseconds
- ✅ Verify webhook is registered correctly in Magic Hour
- ✅ Check that your endpoint URL is correct
- ✅ Ensure headers are being received (log all headers for debugging)
Debug Mode
Add debug logging to troubleshoot signature issues:Next Steps
Event Types Reference
Learn about all available webhook events and their payloads
Production Deployment
Deploy secure webhook handlers to production
Webhook Quickstart
Start with basic webhook setup and testing
API Reference
Complete webhook API documentation