guides
Testing Webhook Responses for MailSlurp Events
Test MailSlurp webhooks with synthetic payloads and real inbound email. Verify duplicate handling, failed storage, retries, and completed application work.
Use with your tools
A webhook test should tell you whether an incoming email becomes the right ticket, record, or notification. A successful HTTP response is a useful checkpoint, but it can still hide a job that was never saved or a worker that failed later.
Use two kinds of test with MailSlurp: a synthetic webhook to check the receiver connection, then a real inbound email to exercise message retrieval and the application result. Keeping those tests separate makes a failure much easier to locate.
What a successful webhook response proves
MailSlurp posts an event to the registered endpoint and records the response. A 200-299 status acknowledges that delivery attempt; redirects and error responses are unsuccessful. Network failures can also lead to retries. Check the webhook delivery documentation for setup and result inspection.
Your receiver should return success only after authentication, validation, and durable acceptance of the pending work. The worker can then process that job separately. If storage fails, return an error instead of acknowledging work that will disappear.
There are three results to check:
| Stage | Evidence to inspect |
|---|---|
| MailSlurp sent the callback | Webhook result and HTTP response status |
| Your receiver accepted the work | A durable job associated with the notification's messageId |
| Your application finished | The expected ticket, record, or other customer-visible result, created once |
Send a synthetic webhook to your endpoint
First create a test inbox and a NEW_EMAIL webhook pointing at your own HTTPS test receiver. Use a test environment where a synthetic event cannot send a customer notification or update production records.
The following command calls MailSlurp's test-data endpoint. Set MAILSLURP_API_KEY and WEBHOOK_ID to your test account key and the webhook ID returned during creation:
curl --fail-with-body -sS -X POST \
"https://api.mailslurp.com/webhooks/$WEBHOOK_ID/test" \
-H "x-api-key: $MAILSLURP_API_KEY"
Inspect the returned request and response details as well as your receiver's logs. This is generated test data: its email ID must not be assumed to identify a stored email that a worker can fetch. Use it to check reachability, authentication handling, payload parsing, and response behavior. Use a real received email for the next test.
For an isolated parser test, you can obtain the documented payload shape without delivering a webhook:
curl --fail-with-body -sS \
"https://api.mailslurp.com/webhooks/test/new-email-payload" \
-H "x-api-key: $MAILSLURP_API_KEY"
A sample payload is not an authenticated HTTP request. Test missing or invalid signature headers separately, using the receiver's verification step.
Follow a real email through the worker
- Create a dedicated inbox and register its webhook before sending.
- Send a controlled email through the application's normal provider, with a unique test reference.
- Wait for that email in MailSlurp and retain its
id. - Check that the callback has the expected
inboxId,webhookId,eventName, andemailId. - Find the receiver's durable job using the callback's
messageId. - Let the worker fetch the email by
emailIdand perform its task. - Assert the resulting record contains the unique test reference and belongs to the correct account.
Use a bounded wait for each asynchronous stage. A timeout should report which stage failed, rather than collapsing everything into "webhook failed." Clean up the test webhook, inbox, and application records when the test finishes.
The two IDs are deliberately different. messageId identifies the webhook notification for deduplication. emailId identifies the email for retrieval. Do not substitute one for the other.
Test the failures that can lose or duplicate work
| Scenario | Expected behavior |
|---|---|
| Same notification arrives twice | Both valid deliveries can receive success; one pending job exists for the messageId |
| Two copies arrive concurrently | A storage uniqueness constraint prevents two jobs |
| Storage fails before commit | Receiver returns an error; no success acknowledgement |
| Commit succeeds but the HTTP response is lost | Retried notification finds the existing job and does not create another |
| Worker crashes after creating a ticket | Worker retry uses the downstream idempotency key or stored result to avoid a second ticket |
| Missing or invalid signature | Request is rejected and no job is created |
| Unexpected inbox or webhook ID | Request is rejected without crossing into another workflow |
Receiver returns 302 or 500 |
Delivery is unsuccessful; inspect the result and subsequent retry behavior |
Receiver returns 200 with an empty body |
HTTP acknowledgement can succeed; a JSON response body is not required to prove receipt |
A malformed response body alone does not establish webhook failure. The response status and transport outcome matter. Conversely, a tidy {"ok":true} response does not prove that your worker completed anything.
Inspect delivery history without losing the application result
Use the dashboard's webhook history or request recent results:
curl --fail-with-body -sS \
"https://api.mailslurp.com/webhooks/$WEBHOOK_ID/results?sort=DESC&size=20" \
-H "x-api-key: $MAILSLURP_API_KEY"
Match results to the intended webhook and test message. An older successful attempt is not evidence for the email you just sent. Keep the email ID, notification ID, job state, and resulting application record together in your test output; redact message content and credentials.
If MailSlurp recorded success but the ticket is missing, inspect your queue and worker. If it recorded a failed delivery, inspect the callback URL, authentication, receiver response, and retry history. Reliable webhook processing explains how durable jobs and recovery fit together.
For local development, a temporary HTTPS tunnel can expose a test receiver. Keep authentication enabled, avoid real customer mail in the test, and remove the webhook before closing the tunnel.
Can I test an email webhook without sending an email?
Yes. The test-data endpoint exercises the callback using synthetic data. A real-message test separately proves that the received email can be fetched and processed into the expected result.
Does a successful webhook mean the email reached a customer's inbox?
A successful callback means your receiver acknowledged an event. For NEW_EMAIL, the event concerns an email received by the subscribed MailSlurp inbox. Customer inbox or spam placement is a separate measurement, covered by inbox placement testing.
When the receiver passes these checks, use the email-to-webhook implementation guide to connect the same pattern to support intake, attachment processing, or inbound routing.