"for": ["tests", "agents"]

Mail in.{JSON} out.

Programmable inboxes for your tests and your agents. Create any address on the fly, wait for the email, get the code or link back as JSON. For CI pipelines and AI agents.

Free tier included. No credit card required.

From: Acme <[email protected]>
Subject: Your Acme code
Content-Type: text/plain
Hi there,
Use 847291 to verify your email,
or open acme.com/verify?t=9c1e…
Thanks,
The Acme team
email.received
{
"email": {
"subject": "Your Acme code",
"links": ["https://acme.com/verify?t=9c1e…"]
},
"otp": { "code": "847291", "source": "body" }
}

"how": [

An inbox of its own, in three calls.

  1. 01

    Add the MCP server

    One command in Claude Code, or a few lines of JSON in any MCP client. Your project API key is the only setting.

  2. 02

    The agent calls create_inbox

    It gets a fresh address of its own, plus the timestamp to wait from, and types the address into the sign-up form.

  3. 03

    It waits for the code

    wait_for_email holds until the message lands and returns the code and links as JSON. No inbox scraping, no regex.

acme.com/signup
Create your account
We’ll email you a 6-digit code
Verification code
6-digit code
Create accountVerifying emailAccount verified
Agent
Sign up for Acme with a new inbox and verify the email.
create_inboxreceiver
wait_for_emailreceiver
847291
claude mcp add receiver \
  -e RECEIVER_API_KEY=recv_live_... \
  -- npx -y @receiverdotemail/mcp

]

"answers": [

Three types of answer, all typed.

Ask for what you need and get it back as JSON, already extracted. No HTML scraping, no regex.

"code": "847291"

The code

Four, six or eight digits, found in the subject or the body, and we tell you which.

"email": { subject, text }

The message

Sender, subject and body as text or HTML, with attachments when you need them.

]

"features": {

Everything an inbox needs to be programmable.

No SMTP server, no DNS, no mailbox to log in to. Mail lands, gets parsed, and waits for you as JSON.

Signed webhooks. Every email posted to your endpoint as email.received, signed and retried.

POSTci.northwind.dev/hooks/mail Delivering
type
"email.received"
Receiver-Signature
t=1762358400,v1=5f2c9e0a…
HMAC-SHA256 verified84 ms · attempt 1 of 3
Mail usually lands within2sLong-polling returns the moment it arrives, so tests wait for mail instead of sleeping.

Unlimited addresses. Every prefix under your suffix is an inbox. Nothing to register first.

"reset-42"

Isolated projects. Each with its own addresses, mail and API keys. One per test suite, agent or team.

Checkout suite"*[email protected]"recv_live_k7m2…

Four ways in. REST API, TypeScript and Python SDKs, an MCP server for agents and a CLI. Same answers from each.

RESTGET /emails/waitTSwaitForOtp()MCPcreate_inboxCLIreceiver otpPYwait_for_otp()RESTPOST /inboxes
MCPwait_for_emailPYpip install receiverdotemailCLIreceiver watchRESTGET /emails/streamTSinboxes.create()
CLIreceiver inbox newTSnpm i @receiverdotemail/sdkMCPget_emailRESTGET /emails/otpPYemails.wait_for()

}

"stack": [

Drop it into the tests you already have.

More in the guides: CI/CD, Jest / Vitest, Pytest and agents.

password-reset.test.tsJest / Vitest
1import { ReceiverClient } from "@receiverdotemail/sdk";2 3const receiver = new ReceiverClient({4  apiKey: process.env.RECEIVER_API_KEY,5});6 7it("sends a reset email with a working link", async () => {8  const inbox = await receiver.inboxes.create({ prefix: "reset" });9  await app.requestPasswordReset(inbox.address);10 11  const email = await receiver.emails.waitFor({12    recipient: inbox.address,13    since: inbox.createdAt,14    timeout: 30,15  });16 17  expect(email.subject).toContain("Reset");18  expect(email.links.some((l) => l.includes("/reset"))).toBe(true);19});
test_login.pyPytest
1import os, pytest2from receiverdotemail import ReceiverClient3 4@pytest.fixture5async def receiver():6    async with ReceiverClient(7        api_key=os.environ["RECEIVER_API_KEY"]8    ) as client:9        yield client10 11async def test_login_code(receiver, app):12    inbox = await receiver.inboxes.create(prefix="login")13    await app.send_login_code(inbox.address)14 15    otp = await receiver.emails.wait_for_otp(16        recipient=inbox.address,17        since=inbox.created_at,18        timeout=30,19    )20    assert len(otp.code) == 6

"plans": [

Simple pricing. Start free.

Pay for volume when you need it. Every plan has every feature, from the MCP server to signed webhooks.

Give your tests and agents an inbox.

Create a free project, copy an API key and receive your first email in a few minutes. No credit card required.