v1 Public beta

A real inbox for tests & agents.

Create a throwaway email, catch the verification mail, extract the code in three HTTP calls. No IMAP, no browser automation, no SDK install. Ships with an MCP server for agents.

No credit card · 50 inboxes / month free · MCP-native
verify-signup · example
# Dispatch a disposable inbox
$ curl -X POST api.mailsink.dev/v1/inboxes
# signup-k8m2@codenotify.net

# ...your app or agent signs up with that address...

# Wait for the verification mail, get the code
$ curl api.mailsink.dev/v1/inboxes/inb_rae1z/wait-for-code
# { "code": "847291", "from": "stripe.com" }
Verified against the senders that matter to test suites and agent runs.
How it works

Three API calls. That's the whole thing.

Standard REST with a bearer token. No SDK. No OAuth flow. No IMAP credentials. Works from a CI runner, a Playwright suite, or an agent runtime. Anything that can make an HTTP request.

01

Create an inbox

POST /v1/inboxes returns a live email address, an id, and a TTL. Use a shared domain from the free tier, or your own domain on Pro.

POST /v1/inboxes
{ "local_part": "signup", "ttl": 3600 }

// → 201
{
  "id": "inb_rae1z",
  "address": signup-k8m2@codenotify.net
}
02

Use the address

Feed it into the signup form, the password reset, the test harness, wherever a real email would go. Mail arrives in milliseconds. No polling required; the wait_for_email endpoint blocks until one lands.

// Playwright
await page.fill(
  '#email',
  'signup-k8m2@codenotify.net'
);
await page.click('#submit');

// The mail is already on its way.
03

Extract the code

GET /v1/inboxes/:id/latest-code parses the message and returns the OTP or magic link as JSON. No regex on your end. Basic extraction, with honest limits documented per sender.

GET /v1/inboxes/inb_rae1z/latest-code

// → 200
{
  "code": "847291",
  "from": "noreply@stripe.com",
  "subject": "Your verification code"
}
MCP server

Your agent talks to the inbox directly.

MailSink ships an MCP server as an npm package. Once installed, your agent has native tools for creating inboxes, waiting on mail, and returning codes, same as any other tool.

Works in Claude Code, Cursor, Windsurf, and any other runtime that speaks MCP. Configuration is a one-line entry in your agent config.

No wrapper scripts. No SDK versioning. No brittle browser automation to drive a signup.

$ npm i @mailsink/mcp
ToolPurpose
create_inboxProvision a throwaway address and return its id.
wait_for_emailBlock up to timeout seconds until a message arrives.
get_verification_codeReturn the OTP from the latest message.
get_verification_linkReturn the magic link from the latest message.
list_messagesEnumerate everything the inbox has received.
delete_inboxDispose of the inbox before its TTL.
Without MailSinkglue code
~14 lines · handwritten · fragile
// Spin up a disposable browser session
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://temp-mail.xyz');
const addr = await page.textContent('.addr');

// Run the signup, poll until mail lands
await signupFlow(addr);
for (let i = 0; i < 30; i++) {
  if (await page.$('.inbox-msg')) break;
  await page.reload();
  await sleep(1000);
}

// Scrape the body, regex the OTP
const body = await page.textContent('.body');
const otp = body.match(/\d{6}/)?.[0];
The pipeline you keep fixing instead of shipping features. It breaks every time Stripe rotates its blocklist.
With MailSink MCPtwo tool calls
7 lines · typed · native
// Your agent calls two typed tools
create_inbox({ ttl: 3600 })
// → signup-k8m2@codenotify.net

// ...agent performs the signup...

get_verification_code({ inbox_id, timeout: 30 })
// → { code: "847291" }
Works in Claude Code, Cursor, Windsurf. Your domain on Pro, so deliverability isn't a gamble.
Why MailSink

Questions we'd ask in your shoes.

01
Why not roll your own?

Because IMAP is a tax, not a solution.

Provisioning mailboxes, rotating credentials, parsing MIME, keeping the domain off blocklists. That's a full-time job. We've done the job. You get the API.

02
Why not a persistent-inbox service?

You don't need the warehouse.

Services for persistent agent identities charge for storage, organisation, and long-term threading. For test signups and OTP flows you want the opposite shape: arrive, extract, vanish.

03
Why not a disposable-email website?

Agents need an API, not a webpage.

The public disposable-email sites are built for humans clicking through a UI. No programmatic access, shared domains that get blocked by the hour, and TOS that ban automation.

04
Why not Mailtrap-class QA tooling?

You can. Pair them.

Mailtrap is optimised for developers inspecting message content during local QA. MailSink is optimised for CI runners and agents that need to act on the mail, not stare at it.

Infrastructure

A domain pool that rotates. Edge that doesn't sleep.

Rotating shared domains

Every inbox lives on one of our shared domains. When a blocklist kicks in on one, new inboxes auto-provision on a clean one and the affected domain rotates out until it clears. You don't manage DNS, you don't babysit reputation.

POOLcodenotify.net · letterhub.net · mailkite.net
SOONBring-your-own-domain on Pro — join waitlist

Dispatched from the edge

MailSink runs on Cloudflare Workers with D1 for metadata and R2 for storage. There's no region to pick, no cold starts, and no servers to nurse. The API responds where your CI or your agent already is.

18ms
p50 response
320+
edge locations
Pricing

Free for hobby. Fair for teams.

Start on the free tier while you're wiring it up. Move to Pro when shared domains slow you down. Month-to-month, no seat pricing, no hidden usage cliffs.

Free
$0 / forever

For wiring it up and personal projects.

  • 50 inboxes / month
  • 1 hour max TTL
  • OTP & link extraction
  • 60 requests / minute
  • MCP server included
Start free →
Team
$49 / month

For CI farms, agencies, and agent platforms.

  • 20,000 inboxes / month
  • 7 day TTL, 5 MB email size
  • 3,000 requests / minute
  • Priority email support
  • MCP server included
Get Team →
FAQ

A few things you'll want to know first.

How reliable is the extraction?
Good against common senders: Stripe, GitHub, Google, Clerk, Supabase, Auth0, Resend, AWS, and dozens more. We describe it honestly as basic extraction and document supported patterns per sender. If a sender isn't supported, you can still read the raw message body via GET /v1/messages/:id.
Can I use this to sign up for services I don't own?
No. MailSink is for testing your own signup flows, CI email verification, and authorised agent workflows. Creating accounts on third-party services in violation of their terms is prohibited and we'll cut off accounts that do it. Be honest about the use case and we'll be on the same side.
How long do emails stick around?
Exactly as long as the TTL you set, then they're removed from R2 and D1. Free: 1 hour. Pro: 24 hours. Team: 7 days. No backup copies, no "just in case" retention.
Do you support webhooks?
Not in the first release. The MCP tool does long-polling with a timeout (wait_for_email), which covers the common agent case. Webhooks are on the roadmap once we see how teams actually use the API.
Can I self-host?
Not yet. The SMTP ingress plus Cloudflare Workers stack isn't trivial to package for self-hosting, so we're focused on the hosted product first. If this is a hard requirement for your team, email and make the case.
What happens if a shared domain gets blocklisted?
We rotate shared domains across a reserve pool and monitor delivery. When a sender flags one, new inboxes auto-provision on a clean domain until it clears. Bring-your-own-domain is coming soon for customers who need a permanent dedicated namespace. Join the waitlist.

Ship the flow you keep postponing.

GitHub sign-in. Ten seconds. No credit card. Your first inbox is live before the kettle boils.