Verifying Webhooks
When building webhook receivers, it’s critical to verify that incoming requests actually originate from AgentMail and haven’t been tampered with. AgentMail uses Svix to deliver webhooks, which provides cryptographic signature verification.
Why Verify Webhooks?
Without verification, anyone who discovers your webhook URL could send fake requests to your endpoint, potentially causing:
- Data manipulation: Malicious actors could trigger actions based on fake events
- Security breaches: Spoofed messages could inject harmful data into your systems
- Resource exhaustion: Attackers could flood your endpoint with fake requests
Always verify webhook signatures in production environments.
Getting Your Signing Secret
Each webhook endpoint has a unique signing secret that you’ll use to verify requests. You can find this secret in the AgentMail console when you create your webhook or by fetching your webhook details:
Keep your secret safe
Store your signing secret securely in environment variables. Never commit it to version control or expose it in client-side code.
Verification Headers
Every webhook request from AgentMail includes three headers used for verification:
Verifying with the Svix Library (Recommended)
The easiest way to verify webhooks is using the official Svix library, which handles all the cryptographic details for you.
Raw body required
Signature verification requires the exact request body. If you’re using body-parsing middleware (like express.json()), make sure to capture the raw body before parsing, or use express.raw() for your webhook endpoint.
Testing Locally with ngrok
During development, you’ll need a way for AgentMail to reach your local server. ngrok creates a public URL that tunnels to your local machine.
Step 1: Save Your Webhook Server
Create a webhook server file:
Step 2: Install Dependencies and Run the Server
You should see output like:
Step 3: Start ngrok
In a new terminal window, start ngrok to create a public tunnel to your local server:
ngrok will display a forwarding URL:
Copy the https:// forwarding URL (e.g., https://da550b82a183.ngrok.app).
Step 4: Add the URL to AgentMail Console
- Go to the AgentMail Console
- Navigate to Webhooks in the sidebar
- Click Create Webhook (or edit an existing one)
- Paste your ngrok URL with the
/webhookspath:https://da550b82a183.ngrok.app/webhooks - Select the events you want to receive
- Save the webhook
- Copy the signing secret and add it to your
.envfile:
Step 5: Trigger a Test Event
Send an email to one of your AgentMail inboxes, or use the console to send a test event. You should see the webhook received in your terminal:
Ready for production?
ngrok is great for local development, but for production you’ll need to deploy your webhook server to a hosting provider. See the next section for deployment options.
Deploying to Production
For production, you’ll need to deploy your webhook server to a hosting provider that gives you a stable, public HTTPS URL. We recommend Render for its simplicity and generous free tier.
Best Practices
Always verify in production
While you might skip verification during local development, always enable it in production environments. A compromised webhook endpoint can be a serious security vulnerability.
Use environment variables
Never hardcode your signing secret. Use environment variables or a secrets manager:
Troubleshooting
Signature verification fails
- Ensure you’re using the raw request body, not a parsed/modified version
- Check that your signing secret is correct and matches the webhook endpoint
- Verify you’re extracting headers correctly (they’re case-insensitive)
- Make sure the timestamp hasn’t expired (default tolerance is 5 minutes)
Missing headers
If headers are missing, ensure your server/framework isn’t stripping them. Some reverse proxies may need configuration to pass through custom headers.
Body parsing issues
If you’re using body-parsing middleware, make sure to access the raw body for verification. In Express, use express.raw() for your webhook route.
