Webhook Documentation

Use MailSlurp webhooks to receive new emails, contacts, or attachments as they arrive via HTTP POST to your server.

Email Webhooks

How does it work?

You can create webhooks for different event and attach them to an inbox. This means that when the given event is triggered a payload is sent to your webhook URL. You server can then process the event and take further actions.

See the webhook guide for more information.

Delivery

A payload is sent via HTTP POST to your server. If it responds with a 200 or 201 status code within 30 seconds the webhook event is marked as successfully processed. If the server does not respond in time or throws an exception the event will be retried until it is successfully handled and you will receive a notification via email of failure.

Webhook creation

You can create a webhook for any MailSlurp inbox using the WebhookController.

mailslurp.webhookController.createWebhook(inboxId, {
    url: "https://my-server.com/webhook",
    eventName: "NEW_EMAIL"
})

Event name can be NEW_EMAIL, NEW_CONTACT, NEW_ATTACHMENT. If omitted the legacy EMAIL_RECEIVED event is used. The payloads sent to your server depend on the event name you use.

Endpoint URL

Provide MailSlurp with a reachable URL endpoint to POST event payloads to. It must be reachable to outside servers. You can provide basic auth credentials for a username and password if required.

Inbox scope

Webhooks are attached to inboxes using the WebhookController and their events are trigger per inbox.

Event types

Webhook have event types that determine the payload that will be sent to your endpoint.

Legacy webhooks use the EMAIL_RECEIVED event and they are sent the associated payload. You can create a webhook for other events such as NEW_EMAIL, NEW_CONTACT, and NEW_ATTACHMENT. For integration with Google Drive and other services please see our Zapier plugin.

Get test payloads

You can fetch test payloads for every event type using the /webhooks/test endpoint.

$ curl api.mailslurp.com/webhooks/test?eventName=EMAIL_RECEIVED
> {"messageId":"message-id-123","webhookId":"d3d7eff1-d2a6-4b8b-b112-e08c9f0f144b","webhookName":"test-webhook","eventName":"EMAIL_RECEIVED","inboxId":"94a2be75-4350-48b1-b53d-92183b1fa52d","emailId":"13b21e2b-0a29-406c-a4c0-0251171d6417","createdAt":"2021-05-14T02:19:25.826Z","to":["a@b.com"],"from":"test@gmail.com","cc":[],"bcc":[],"subject":"Test email received","attachmentMetaDatas":[]}

Deserializing webhook data

Consult the schema documentation below or use the Webhook payload classes to deserialize JSON payloads in your server.

Documentation

NEW_EMAIL

This payload is sent via HTTP POST to your webhook URL when a new email is received by MailSlurp that matches optional filters. You can provide filters when creating the webhook. Use the EmailController with the emailId to fetch the body of the email or headers. To receive attachments or use the NEW_ATTACHMENT webhook.

NameTypeNullableDescription
messageIdjava.lang.StringfalseIdempotent message ID. Store this ID locally or in a database to prevent message duplication.
webhookIdjava.util.UUIDfalseID of webhook entity being triggered
eventNamecom.mailslurp.lib.dtos.webhook.WebhookEventNamefalseName of the event type webhook is being triggered for.
webhookNamejava.lang.StringtrueName of the webhook being triggered
inboxIdjava.util.UUIDfalseId of the inbox that received an email
emailIdjava.util.UUIDfalseID of the email that was received. Use this ID for fetching the email with the EmailController.
createdAtjava.time.InstantfalseDate time of event creation
tojava.util.List<java.lang.String>falseList of To recipient email addresses that the email was addressed to. See recipients object for names.
fromjava.lang.StringfalseWho the email was sent from. An email address - see fromName for the sender name.
ccjava.util.List<java.lang.String>falseList of CC recipients email addresses that the email was addressed to. See recipients object for names.
bccjava.util.List<java.lang.String>falseList of BCC recipients email addresses that the email was addressed to. See recipients object for names.
subjectjava.lang.StringtrueThe subject line of the email message as specified by SMTP subject header
attachmentMetaDatasjava.util.List<com.mailslurp.lib.dtos.attachment.AttachmentMetaData>falseList of attachment meta data objects if attachments present

NEW_CONTACT

Triggered when a new contact is found. If the addNewContacts setting is enabled for your account MailSlurp will parse any new recipients or senders for a received email and save them to your contacts. Saved contacts are sent via HTTP POST to your webhook URL using this payload.

NameTypeNullableDescription
messageIdjava.lang.StringfalseIdempotent message ID. Store this ID locally or in a database to prevent message duplication.
webhookIdjava.util.UUIDfalseID of webhook entity being triggered
webhookNamejava.lang.StringtrueName of the webhook being triggered
eventNamecom.mailslurp.lib.dtos.webhook.WebhookEventNamefalseName of the event type webhook is being triggered for.
contactIdjava.util.UUIDfalse
groupIdjava.util.UUIDfalse
firstNamejava.lang.Stringfalse
lastNamejava.lang.Stringfalse
companyjava.lang.Stringfalse
primaryEmailAddressjava.lang.Stringfalse
emailAddressesjava.util.Set<java.lang.String>false
tagsjava.util.Set<java.lang.String>false
metaDatacom.fasterxml.jackson.databind.JsonNodefalse
optOutjava.lang.Booleanfalse
createdAtjava.time.Instantfalse

NEW_ATTACHMENT

When a new email is received by MailSlurp the attachments are parsed and saved to storage. If a NEW_ATTACHMENT webhook is enabled for the receiving inbox this payload will be sent via HTTP POST to the webhooks URL. An attachment ID, name, and meta data are included. Use the attachmentId with the AttachmentController to access the file content as byte stream or base64 encoded string to download the file.

NameTypeNullableDescription
messageIdjava.lang.StringfalseIdempotent message ID. Store this ID locally or in a database to prevent message duplication.
webhookIdjava.util.UUIDfalseID of webhook entity being triggered
webhookNamejava.lang.StringtrueName of the webhook being triggered
eventNamecom.mailslurp.lib.dtos.webhook.WebhookEventNamefalseName of the event type webhook is being triggered for.
attachmentIdjava.lang.StringfalseID of attachment. Use the AttachmentController to
namejava.lang.StringfalseFilename of the attachment if present
contentTypejava.lang.StringfalseContent type of attachment such as ‘image/png’ or ‘application/pdf
contentLengthlongfalseSize of attachment in bytes

EMAIL_READ

This payload is sent via HTTP POST to your webhook URL when an email is read. This is when the email is requested from the API in full format or is viewed in the dashboard

NameTypeNullableDescription
messageIdjava.lang.StringfalseIdempotent message ID. Store this ID locally or in a database to prevent message duplication.
webhookIdjava.util.UUIDfalseID of webhook entity being triggered
eventNamecom.mailslurp.lib.dtos.webhook.WebhookEventNamefalseName of the event type webhook is being triggered for.
webhookNamejava.lang.StringtrueName of the webhook being triggered
emailIdjava.util.UUIDfalseID of the email that was received. Use this ID for fetching the email with the EmailController.
inboxIdjava.util.UUIDfalseId of the inbox that received an email
emailIsReadbooleanfalseIs the email read
createdAtjava.time.InstantfalseDate time of event creation

EMAIL_OPENED

This payload is sent via HTTP POST to your webhook URL when an email containing a tracking pixel is opened. Triggered for pixels in emails sent from the inbox that the webhook is attached to

NameTypeNullableDescription
messageIdjava.lang.StringfalseIdempotent message ID. Store this ID locally or in a database to prevent message duplication.
webhookIdjava.util.UUIDfalseID of webhook entity being triggered
eventNamecom.mailslurp.lib.dtos.webhook.WebhookEventNamefalseName of the event type webhook is being triggered for.
webhookNamejava.lang.StringtrueName of the webhook being triggered
inboxIdjava.util.UUIDfalseId of the inbox that received an email
pixelIdjava.util.UUIDfalseID of the tracking pixel
sentEmailIdjava.util.UUIDfalseID of sent email
recipientjava.lang.StringfalseEmail address for the recipient of the tracking pixel
createdAtjava.time.InstantfalseDate time of event creation

EMAIL_RECEIVED

Legacy webhook payload for EMAIL_RECEIVED webhooks or webhooks with no defined event type. Use the NEW_EMAIL webhook instead as it sends you a full EmailDto.

NameTypeNullableDescription
messageIdjava.lang.StringfalseIdempotent message ID. Store this ID locally or in a database to prevent message duplication.
webhookIdjava.util.UUIDfalseID of webhook entity being triggered
webhookNamejava.lang.StringtrueName of the webhook being triggered
eventNamecom.mailslurp.lib.dtos.webhook.WebhookEventNamefalseName of the event type webhook is being triggered for.
inboxIdjava.util.UUIDfalseId of the inbox that received an email
emailIdjava.util.UUIDfalseID of the email that was received. Use this ID for fetching the email with the EmailController.
createdAtjava.time.InstantfalseDate time of event creation
tojava.util.List<java.lang.String>falseList of To recipient email addresses that the email was addressed to. See recipients object for names.
fromjava.lang.StringfalseWho the email was sent from. An email address - see fromName for the sender name.
ccjava.util.List<java.lang.String>falseList of CC recipients email addresses that the email was addressed to. See recipients object for names.
bccjava.util.List<java.lang.String>falseList of BCC recipients email addresses that the email was addressed to. See recipients object for names.
subjectjava.lang.StringtrueThe subject line of the email message as specified by SMTP subject header
attachmentMetaDatasjava.util.List<com.mailslurp.lib.dtos.attachment.AttachmentMetaData>falseList of attachment meta data objects if attachments present

Testing webhooks

You can use the MailSlurp dashboard to test webhooks. You can also see your webhook history in the dashboard. Here is an example demonstrating webhook behaviour using Jest, the MailSlurp NodeJS client and the webhook testing library @mailslurp/test-webhooks:

import fetchApi from "isomorphic-fetch";
import {CreateWebhookOptions, MailSlurp} from "mailslurp-client"
import {
    Configuration as TestWebhookConfiguration,
    CreateRulesetOptionsStrategyEnum,
    DefaultApi as TestWebhookApi
} from '@mailslurp/test-webhooks'

jest.setTimeout(60000)
const apiKey = process.env.apiKey;
const mailslurp = new MailSlurp({apiKey, fetchApi})
const testWebhooks = new TestWebhookApi(new TestWebhookConfiguration())

describe("NEW_EMAIL webhooks", () => {
    test('can create NEW_EMAIL webhook and receive successfully', async () => {
        // create an inbox, webhook, and a test endpoint
        const testEndpoint = await testWebhooks.createEndpoint({})
        const inbox = await mailslurp.createInbox()
        const webhook = await mailslurp.webhookController.createWebhook(inbox.id!, {
            eventName: CreateWebhookOptions.EventNameEnum.NEWEMAIL,
            url: testEndpoint.url
        })
        // can see that endpoint has not received an event
        const endpointHistory = await testWebhooks.getEndpointHistory({endpointId: testEndpoint.id!})
        expect(endpointHistory.items?.length).toEqual(0)
        // send email to inbox
        await mailslurp.sendEmail(inbox.id!, {to: [inbox.emailAddress!], subject: 'email1'})
        // can fetch the email directly
        const email = await mailslurp.waitForLatestEmail(inbox.id!, 60000, true)
        expect(email.subject).toEqual("email1")
        // endpoint receives the payload (note the expected length to wait for)
        const endpointHistory2 = await testWebhooks.getEndpointHistory({
            endpointId: testEndpoint.id!,
            expectedLength: 1
        })
        expect(endpointHistory2.items?.length).toEqual(1)

        // assert correct payload was sent to endpoint
        const payload = JSON.parse(endpointHistory2.items?.[0]?.request?.body!)
        expect(payload.webhookId).toEqual(webhook.id)
        expect(payload.eventName).toEqual("NEW_EMAIL")
        expect(payload.inboxId).toEqual(inbox.id)
        expect(payload.emailId).toEqual(email.id)
        expect(payload.to).toEqual([inbox.emailAddress])
        expect(payload.from).toEqual(inbox.emailAddress)
        expect(payload.subject).toEqual("email1")

        // can see webhook results via mailslurp
        const results = await mailslurp.webhookController.getWebhookResults(webhook.id!)
        expect(results.totalElements).toEqual(1)
        const result = await mailslurp.webhookController.getWebhookResult(results.content?.[0]?.id!)
        expect(result.resultType).toEqual('SUCCESS')
        expect(result.responseStatus).toEqual(200)

        await mailslurp.webhookController.deleteWebhook(inbox.id!, webhook.id!)
    })

    test('can create NEW_EMAIL webhook and see failed results when endpoint fails to accept payload', async () => {
        // create a test endpoint that always returns a 401 error
        const testEndpoint = await testWebhooks.createEndpoint({})
        await testWebhooks.addEndpointRuleset({
            endpointId: testEndpoint.id!,
            createRulesetOptions: {
                strategy: CreateRulesetOptionsStrategyEnum.SINGULAR,
                responses: [{
                    statusCode: 401
                }]
            }
        })

        // create inbox and webhook
        const inbox = await mailslurp.createInbox()
        const webhook = await mailslurp.webhookController.createWebhook(inbox.id!, {
            eventName: CreateWebhookOptions.EventNameEnum.NEWEMAIL,
            url: testEndpoint.url
        })

        // send email to inbox
        await mailslurp.sendEmail(inbox.id!, {to: [inbox.emailAddress!], subject: 'email2'})

        // wait for endpoint to receive payload
        const endpointHistory = await testWebhooks.getEndpointHistory({
            endpointId: testEndpoint.id!,
            expectedLength: 1
        })
        expect(endpointHistory.items?.length).toEqual(1)

        // can see webhook results via mailslurp
        const results = await mailslurp.webhookController.getWebhookResults(webhook.id!)
        expect(results.totalElements).toEqual(1)
        const result = await mailslurp.webhookController.getWebhookResult(results.content?.[0]?.id!)
        expect(result.resultType).toEqual('BAD_RESPONSE')
        expect(result.responseStatus).toEqual(401)

        await mailslurp.webhookController.deleteWebhook(inbox.id!, webhook.id!)
    })
})

For more testing examples see the webhook testing guide.

Further reading

Please see the Webhooks guide for more information and examples.