MailSlurp logo

about

Email APIs for Developers

Build reliable email and SMS workflows with MailSlurp APIs and SDKs: create inboxes, send messages, receive inbound events, and assert outcomes in tests.

MailSlurp gives developers a programmable way to test and automate messaging workflows without relying on fragile shared inboxes.

Start here:

Pick a starting workflow

Goal First API action Next step
Test signup and verification Create an inbox per test Wait for email and assert code/link
Automate inbound processing Attach webhook or poll messages Parse and route to your service
Validate campaign quality Send controlled test messages Check rendering, headers, and auth signals
Build multi-tenant tooling Isolate inboxes by workspace/env Apply key rotation and audit controls

Core developer capabilities

1) Create private inboxes on demand

// create a randomly assigned email address
const mailslurp = new MailSlurp({ apiKey });
const { id, emailAddress } = await mailslurp.createInbox();

Need deterministic addresses for a specific test case or tenant? Use custom address options:

// create a custom email address with your own domain
const customInbox = await mailslurp.createInbox("user@mydomain.com");

2) Receive and assert messages in code

const timeout = 30_000;
// hold connection open until first email found or timeout
const { body, subject, attachments } = await mailslurp.waitForLatestEmail(inbox.id, timeout);
expect(subject).toContain(emailSubject);

// more examples
const nthEmail = await mailslurp.waitForNthEmail(inbox.id!, 0, timeout);
const emailList = await mailslurp.waitForEmailCount(count, inbox.id, timeout);

3) Send email with attachments and templates

const [attachmentId] = await mailslurp.uploadAttachment({
  base64Contents: Buffer.from("test").toString("base64"),
  filename: "test.txt",
  contentType: "text/plain",
});
const sent = await mailslurp.sendEmail(inbox.id!, {
  to: [inbox.emailAddress!],
  subject: emailSubject,
  attachments: [attachmentId.toString()],
});
expect(sent.attachments).toContain(attachmentId);
expect(sent.subject).toContain(emailSubject);

For attachment workflows:

// upload attachments to mailslurp
const file = await fs.promises.readFile(pathToAttachment, {
  encoding: "utf-8",
});
const [id] = await mailslurp.uploadAttachment({
  base64Contents: file.toString("base64"),
  filename: "attachment.txt",
  contentType: "text/plain",
});

// attach the files with id to send
await mailslurp.sendEmail(sendingInbox.id!, {
  to: [recipientAddress],
  attachments: [id.toString()],
});

For templated content:

await mailslurp.sendEmail(sendingInbox.id!, {
  to: [recipientAddress!],
  subject: "Hello {{name}}",
  body: "Dear {{name}}, your code is {{code}}.",
  templateVariables: {
    name: "John" as any,
    code: "123" as any,
  },
});
const received = await mailslurp.waitForLatestEmail(receiveInbox.id, 60_000);
expect(received.subject).toContain("Hello John");
expect(received.body).toContain("Dear John, your code is 123.");

4) Filter and extract structured content

Use wait conditions and matching patterns to reduce flaky tests and avoid brittle polling loops.

// or wait for matching
const matchingEmails = await mailslurp.waitForMatchingEmails(
  {
    conditions: [
      {
        condition: ConditionOptionConditionEnum.HAS_ATTACHMENTS,
        value: ConditionOptionValueEnum.TRUE,
      },
    ],
    matches: [
      {
        field: MatchOptionFieldEnum.SUBJECT,
        should: MatchOptionShouldEnum.CONTAIN,
        value: emailSubject,
      },
    ],
  },
  count,
  inbox.id!,
);
expect(matchingEmails.length).toEqual(1);
expect(matchingEmails[0].subject).toEqual(emailSubject);
await mailslurp.deleteInbox(inbox.id!);

For extraction pipelines:

const user = await myApp.signUp(testInbox.emailAddress!);

// verify that confirmation email was sent by your app
const timeout = 30000;
const email = await mailslurp.waitForLatestEmail(testInbox.id, timeout);

// confirm the user using the code
const [_, verificationCode] = /your code is "([0-9]{6})"/g.exec(email.body!)!;

// do something with code like verifying an account
await myApp.confirmUser(verificationCode);

Delivery architecture for engineering teams

MailSlurp is built for asynchronous systems and CI reliability.

  • queue-backed message processing
  • webhook retries with backoff
  • SDK support across major languages
  • cloud dashboard for operational visibility

Webhook example:

@PostMapping("/inbound-emails")
fun inboundEmail(event: Map<String, String>) {
    val emailId = event["emailId"] ?: return
    // fetch email, parse data, trigger your domain workflow
}

SDK coverage

Official support includes JavaScript, Python, PHP, Java, Go, Ruby, C#, and more. Browse the full MailSlurp SDK docs.

Operational best practices

  • create one inbox per test execution path
  • keep API keys separate per environment
  • assert business outcomes (links, tokens, routing), not just status codes
  • add delivery checks to release gates

Continue with implementation