Frequently asked questions

How to receive and read real verification emails in automated tests: Playwright and Cypress helpers, a plain HTTP API, limits, retention and privacy.

What is receivemail.dev?

A free, real email inbox for automated tests. One API call gives you a fresh @receivemail.dev address; you point your app's signup or password-reset flow at it, then read what arrives. No account, no API key.

How do I test an email verification flow in Playwright?

Install playwright-receivemail. Each test gets its own fresh inbox as a mailbox fixture:

npm i -D playwright-receivemail
import { test, expect } from "playwright-receivemail";

test("a new user can verify their email", async ({ page, mailbox }) => {
  await page.goto("/signup");
  await page.getByLabel("Email").fill(mailbox.address);
  await page.getByRole("button", { name: "Create account" }).click();

  const link = await mailbox.waitForMatch(/https:\/\/[^\s"]+\/verify[^\s"]*/, {
    subjectContains: "verify",
    timeout: 30_000,
  });
  await page.goto(link);
  await expect(page.getByText("Email verified")).toBeVisible();
});

How do I test an email verification flow in Cypress?

Install cypress-receivemail and register its commands in your support file:

npm i -D cypress-receivemail
import { addReceivemailCommands } from "cypress-receivemail";
addReceivemailCommands();

cy.createMailbox().then((mb) => {
  cy.visit("/signup");
  cy.get("input[name=email]").type(mb.address);
  cy.contains("button", "Create account").click();
  cy.getEmailMatch(/\b\d{6}\b/).then((code) => cy.get("input[name=code]").type(code));
});

How do I use it without a library, from curl or any language?

Two HTTP calls. Create a mailbox:

curl -X POST https://receivemail.dev/mailboxes \
  -H 'content-type: application/json' -d '{"ttlMinutes": 15}'
# => {"address":"a1b2c3d4e5f6@receivemail.dev","expiresAt":"...","secret":"..."}

Send your app's email to address, then read it with the secret:

curl https://receivemail.dev/mailboxes/a1b2c3d4e5f6@receivemail.dev/messages \
  -H 'authorization: Bearer <secret>'
# => {"address":"...","messages":[{"from_address":"...","subject":"...","body_text":"...","received_at":"2026-09-26T04:54:46Z"}]}

Poll every few seconds until the message you expect shows up, or call GET /mailboxes/:address/wait?timeout=25 with the same header: it holds the request open and returns as soon as a message arrives ({"timed_out":true} if none does). Messages are newest first; received_at is ISO 8601 in UTC.

How do I pull a 6-digit code or a verification link out of the email?

Match against body_text (or subject). Typical patterns:

const code = body_text.match(/\b\d{6}\b/)?.[0];
const link = body_text.match(/https:\/\/[^\s"]+\/verify[^\s"]*/)?.[0];

The Playwright and Cypress helpers do this for you: pass the regex to waitForMatch / getEmailMatch.

How long does an address live, and how long is mail kept?

You choose the address lifetime with ttlMinutes: 1 to 60 minutes, 15 by default. Received mail is deleted after about 24 hours. Use a new address per test run rather than reusing one.

What are the limits?

Can someone else read my test emails?

Reading a mailbox needs the secret returned when it was created, and addresses are random. Mail sent to an address nobody reserved can't be read through the API. Still, treat these inboxes as throwaway test infrastructure: don't send real users' personal data to them.

Can an AI agent use it?

Yes. The agent-identity-mcp MCP server gives an agent (Claude, Cursor and others) a disposable receivemail.dev inbox for free, plus a real UK phone number for SMS codes through sms-florin (paid). There is also an n8n node.

Is it really free, and what are the alternatives?

Yes, within the limits above. If you need HTML bodies, attachments, custom domains or long-lived inboxes, a paid service such as Mailosaur or MailSlurp fits better; see our comparisons with Mailosaur, MailSlurp and Mailinator.