API reference/feedback
Receive bounce webhooks from an email provider
POST/api/v1/email/feedback/{provider}/{feedbackKey}
- authentication
- Feedback key in the URL
- billing
- Free.
The webhook target for an email provider's bounce, delivery and complaint notifications. Providers cannot send bearer tokens, so the account's feedback key rides in the URL (generate or rotate it on the dashboard's API keys page; rotating invalidates the URLs at once) and the provider name selects the payload adapter. The body is the provider's own payload, decoded as JSON regardless of content type because Amazon SNS posts JSON as text/plain. Payloads are read for their documented fields and nothing else; events that say nothing definitive about the address are ignored.
| Provider | Path | Mapping |
|---|---|---|
| postmark | /api/v1/email/feedback/postmark/{key} |
Bounce (hard types) → bounced · Delivery → delivered · SpamComplaint → complained. Soft bounces are ignored. |
| ses | /api/v1/email/feedback/ses/{key} |
SNS notifications: Bounce with bounceType Permanent → bounced · Delivery → delivered · Complaint → complained. Subscription confirmations are answered. |
| mailgun | /api/v1/email/feedback/mailgun/{key} |
delivered → delivered · failed with severity permanent → bounced · complained → complained. Temporary failures are ignored. |
| sendgrid | /api/v1/email/feedback/sendgrid/{key} |
delivered → delivered · bounce and dropped → bounced · spamreport → complained. Deferred events are ignored. |
Throttled at 120 requests per minute per IP. Outcomes recorded here behave exactly like ones reported through POST /api/v1/email/feedback.
Parameters
| name | in | type | description |
|---|---|---|---|
| providerrequired | path | string | Which provider's payload format to expect. One of: postmark, ses, mailgun, sendgrid. |
| feedbackKeyrequired | path | string | The account's feedback key, which starts with `fb_`. |
Request body
The provider's native webhook payload.
Example request
curl -X POST https://spaw.co/api/v1/email/feedback/postmark/fb_… \
-H "Content-Type: application/json" \
-d '{
"RecordType": "Bounce",
"Type": "HardBounce",
"Email": "[email protected]",
"Description": "The server was unable to deliver your message (ex. unknown user, mailbox not found).",
"BouncedAt": "2026-09-03T10:12:44Z"
}'Responses
200The outcomes the payload carried were recorded.
{
"success": true,
"data": {
"recorded": 1,
"skipped": 0
}
}401The feedback key does not exist or was rotated.
{
"success": false,
"error": {
"code": "INVALID_FEEDBACK_KEY",
"message": "That feedback key does not exist or was rotated.",
"request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
}
}404The provider path is not one of postmark, ses, mailgun, or sendgrid.
{
"success": false,
"error": {
"code": "UNKNOWN_FEEDBACK_PROVIDER",
"message": "Supported providers: postmark, ses, mailgun, sendgrid.",
"request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
}
}429Over 5 requests per second for the key. Retry after the limit resets.
{
"success": false,
"error": {
"code": "RATE_LIMITED",
"message": "Too many requests. Retry after the limit resets.",
"request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
}
}Error codes
Failures answer { success: false, error: { code, message, request_id } }. Each code has its own page.