Webhooks
GoodPostal receives webhook events from your email sending service to track email delivery, opens, clicks, bounces, and complaints in real-time.
How It Works
When you configure webhooks with your sending service, the service sends HTTP POST requests to GoodPostal whenever an email event occurs. GoodPostal parses these events and updates your campaign analytics accordingly.
Webhook URL
Each sending service connection has its own webhook endpoint on GoodPostal. In almost every case you never handle it yourself: GoodPostal configures the webhook on your sending service from Configure > Email Providers. For Amazon SES, the endpoint is also shown on the provider detail page so you can subscribe it to your SNS topic by hand.
https://goodpostal.com/webhooks/{provider}/{unique-token}Supported Events
| Name | Type | Required | Description |
|---|---|---|---|
delivered | event | No | Email was accepted by the recipient mail server |
opened | event | No | Recipient opened the email (tracking pixel loaded) |
clicked | event | No | Recipient clicked a tracked link in the email |
bounced | event | No | Email could not be delivered (hard or soft bounce) |
complained | event | No | Recipient marked the email as spam |
unsubscribed | event | No | Recipient clicked the unsubscribe link |
Signature Verification
GoodPostal verifies webhook signatures to ensure events are genuinely from your sending service. This prevents malicious actors from sending fake events to your webhook endpoint.
Each sending service uses a different signing mechanism:
- SendGrid - ECDSA signature in the
X-Twilio-Email-Event-Webhook-Signatureheader - Mailgun - HMAC-SHA256 using your webhook signing key
- Amazon SES - SNS X.509 certificate verification
- Postmark - HTTP Basic Auth credentials that GoodPostal generates and sets on the webhook
- SMTP2GO - An
Authorization: Bearertoken that GoodPostal generates and sets on the webhook - Mailtrap - HMAC-SHA256 signature in the
Mailtrap-Signatureheader - SMTP - HMAC-SHA256 signature in the
X-Webhook-Signatureheader, with a 5 minute freshness window on the event timestamp
Retry Logic
If GoodPostal returns a non-200 response to a webhook event, most sending services will retry delivery. Retry behavior varies by provider:
- SendGrid - Retries for up to 24 hours with exponential backoff
- Mailgun - Retries with increasing intervals up to 8 hours
- Amazon SES - SNS retries with exponential backoff for up to 23 days
- Postmark - Retries up to 5 times with increasing delays
- SMTP2GO - Retries with exponential backoff
- Mailtrap - Retry behavior is documented by Mailtrap
Event Processing
Webhook events are processed asynchronously using Laravel queues. When GoodPostal receives a webhook, it immediately returns a 200 response and queues the event for processing. This ensures webhook endpoints respond quickly even under high volume.
Sending Service Specific Setup
For detailed webhook configuration instructions for each sending service, see:
- SendGrid Webhook Setup
- Mailgun Webhook Setup
- Amazon SES Webhook Setup
- Postmark Webhook Setup
- SMTP2GO Webhook Setup
- Mailtrap Webhook Setup
- SMTP Webhook Setup
Debugging Webhooks
If events are not appearing in your analytics, check:
- Open Configure > Email Providers, select the service, and look at the Webhook & Tracking card. If the status is not provisioned, use Set up webhooks automatically (or Re-configure webhooks) to retry
- That nobody has edited or deleted GoodPostal's webhook inside your sending service dashboard. Re-configuring rebuilds it
- That your credentials still work. Rotating an API key at the sending service breaks the webhook until you re-configure it