Developer Resources

Temporary Email for Developers: Testing & Automation Guide

TempMailSpot Editorial Team
11 min read

Developer guide to integrating temporary email into your workflow. API usage, automated testing, and best practices for email testing.

Temporary email earns its place in a developer's toolkit for one reason: it lets you exercise a real email flow, signup, verification, password reset, magic link, end to end, without spending your own inbox or creating a permanent test account you then have to clean up. Generate an address, run the flow, read the message that arrives, assert on it, throw the address away.

This guide covers the developer-specific parts. Which APIs you can call straight from test or automation code, how to poll for a message without a flaky fixed sleep, the disposable-domain blocklists that real signup forms use to reject throwaway addresses (and why that is useful to know from both sides), and where a hosted temp inbox is the wrong tool and a local SMTP capture server is the right one. For the mechanics underneath any of these tools, see how disposable email works; for the broader category, the complete guide to temporary email is the pillar above this one.

If you just want an address to test a flow by hand right now, open an inbox: no signup, mail appears on its own within seconds, and you can export anything that arrives.

Key takeaways

  • Use a fresh disposable address per test run so a signup, verification, or password-reset flow can be exercised end to end without burning a real inbox or colliding with a previous account.
  • Real signup forms reject known throwaway domains: PyPI blocks them using the open-source disposable-email-domains list, so a temp address is also the input that tells you whether your own anti-abuse blocklist works.
  • For automated send-and-receive QA, drive a hosted temp-mail API (Mail.tm is free and key-less at 8 queries/sec per IP) and poll for the message with a timeout and backoff rather than a fixed sleep.
  • To inspect mail your own app sends in development or CI, capture it locally with a maintained SMTP sink such as Mailpit on ports 1025/8025; treat the unmaintained MailHog (last release 2018) as legacy.
  • Temporary email tests functionality, not deliverability; it can also miss messages from a localhost SMTP server, so keep delivery testing on real or sandboxed infrastructure.

Where temporary email fits in a dev workflow

Temporary email solves a narrow, common problem: you need a working external mailbox you can read, you need it now, and you do not want it to outlive the test.

The flows it is built for

A disposable inbox is the recipient half of any flow your application drives by email:

FlowWhat you assertWhy temp email helps
Signup / double opt-inConfirmation arrives, link activates the accountA fresh address per run avoids "email already registered"
Email verification codeCode arrives, matches, expires correctlyRead the code without checking a shared inbox
Password resetReset link arrives, single-use, time-limitedNo need to know a real account's password
Magic-link / passwordless loginLink arrives and authenticatesExercise the full round trip, not just the send
Notification / transactional templatesSubject, body, links, and unsubscribe renderSee the message as a recipient sees it

What it is not for

Temporary email checks that a message was sent, routed, and received, and that its contents are correct. It does not measure deliverability, whether your production mail lands in the inbox versus spam at Gmail or Outlook, because disposable providers do not run the reputation, SPF/DKIM/DMARC, and engagement signals that real mailbox providers score. Keep deliverability work on real or sandboxed infrastructure. Our complete developer guide to testing email delivery covers that side in depth.

It is also receive-first. Most disposable services cannot send, and the few that do gate it heavily, so a flow that expects the user to reply needs a tool that can send (more on that below). And never point an account you intend to keep at a disposable address: there is no recovery once the inbox expires.

The blocklist reality: why some signups reject temp addresses

Before you wire a disposable address into a test, know that a meaningful share of real signup forms will refuse it on purpose. This is the single most common surprise developers hit.

The de facto standard is the open-source disposable-email-domains list, "a list of disposable and temporary email address domains often used to register dummy users in order to spam or abuse some services." It is widely adopted; the repository carries roughly 5,100 GitHub stars, and it is consumed by language ecosystems and frameworks rather than just hobby projects.

The most concrete example is PyPI, the Python Package Index. Its maintainers describe blocking throwaway domains as a core anti-abuse control: "One of the most impactful mechanisms we currently have is prohibiting known 'throw-away' email domains from creating accounts on the index," per the disposable-email-domains README. If you try to register a PyPI account with a known disposable domain, you are rejected, by design.

That cuts two ways for a developer:

  • When you are the consumer of someone else's signup form, expect that a generic temp-mail domain may be on a public blocklist and bounce. Some services rotate domains specifically to stay ahead of these lists; do not assume any one domain will be accepted.
  • When you are the author of the signup form, the same list is the building block of your own defense. The reason disposable addresses exist as an abuse vector at all is volume: industry telemetry puts spam at 47.27% of all email sent worldwide in 2024 (Kaspersky), and the APWG tracks roughly 3.4 billion phishing emails sent per day, so deduplicating real users from throwaway sign-ups is a legitimate control. A temp address then becomes a test input in its own right: register with one and assert your form rejects it.

The practical upshot for testing: if you control the application under test, decide deliberately whether the disposable domain is allowed in the test environment, and test both the accept path (a non-blocklisted address) and the reject path (a known disposable domain). This is covered in more depth in how disposable email works.

How a receive-only temp inbox actually receives mail

Understanding the plumbing makes the polling code below less mysterious and the failure modes obvious.

Email routes by DNS. When your application's mail server delivers a message, it looks up the recipient domain's MX (mail exchanger) records and connects over SMTP — the protocol defined by RFC 5321, the Internet Standard whose Section 5 specifies that MX records direct where mail for a domain is delivered. A disposable-email provider points its domain's MX records at its own catch-all server, which accepts mail for any local-part (so any address at its domain works without being provisioned first) and exposes the captured messages over a web UI or an API.

Two consequences matter for tests:

  • A temp inbox can only receive what was actually routed to it over real SMTP from a reachable sender. If your application sends from localhost with no outbound relay, or your dev environment blocks outbound SMTP ports, nothing arrives — and the test fails for an infrastructure reason, not a code reason. For that case, capture mail locally instead (see the local-SMTP section).
  • Because the domain accepts any address, providers control abuse and cost by limiting how long mail is kept and how much. Maildrop, for example, holds a maximum of 10 messages per inbox and erases any inbox idle for 24 hours; it also notes its filters reduce spam by "more than 90%." Those caps are exactly the kind of thing that breaks a long-running test if you assume an inbox is unbounded.

Driving a hosted temp-mail API from test code

For automated send-and-receive QA against an external mailbox, you call a hosted temp-mail API: provision an address, trigger your flow, then poll the API until the expected message arrives. The shape is the same across providers; the limits differ.

Free, key-less options and their real limits

Mail.tm is the most CI-friendly free option. Its REST API is "Completely free. No API key, no signup, no paid tiers," with a documented general quota of "8 queries per second (QPS) per IP address." It is fetch-only: you can create an account and read messages, but not send, which is fine for testing a flow your own app drives.

Guerrilla Mail exposes a public JSON API for getting an address and checking, fetching, and deleting mail. One detail to design your loop around: a single new-mail check returns at most 20 emails, so a high-volume run should fetch and delete rather than letting messages accumulate.

Temp Mail (temp-mail.org) is worth flagging for expectation-setting: its free service is receive-only ("you can only receive messages, not send") and auto-deletes incoming mail within roughly one to two hours. Treat it as verification-only.

A note on send-and-receive across providers: some services that do offer sending block outbound mail to external domains on the free tier specifically to stop spam. MailSlurp, for instance, states that "free accounts cannot send emails to some external (non-MailSlurp) addresses... This is to prevent spam being sent from free MailSlurp accounts" (MailSlurp support). If your test needs the temp address to send a reply, verify the provider permits external sending on your plan before building around it.

A polling pattern that does not flake

The cardinal sin of email tests is a fixed sleep. Mail arrival is variable, so poll with a deadline and a steady interval instead:

// Poll a temp-mail inbox until a matching message arrives, or time out.
async function waitForEmail(checkInbox, { match, timeoutMs = 30_000, intervalMs = 2_000 }) {
  const deadline = Date.now() + timeoutMs;
  while (Date.now() < deadline) {
    const messages = await checkInbox();      // one API call (returns recent mail)
    const hit = messages.find(match);          // e.g. m => /verify/i.test(m.subject)
    if (hit) return hit;
    await new Promise(r => setTimeout(r, intervalMs));
  }
  throw new Error('Timed out waiting for email');
}

// Usage in a test
const inbox = await createInbox();             // provider: create address
await signupUser(inbox.address);               // your app sends the verification mail
const verification = await waitForEmail(
  () => inbox.fetchMessages(),
  { match: m => m.subject.includes('Verify'), timeoutMs: 30_000 }
);
const code = extractCode(verification.text);
await submitVerification(code);

Keep the per-check interval modest. Mail.tm's 8 QPS/IP ceiling is generous for one test but easy to blow with many parallel workers hammering the same IP, so respect provider rate limits and run independent inboxes rather than re-polling one address from a dozen jobs at once. A 30-second total deadline is a reasonable default; allow more for flows known to send slowly.

If you are scripting against TempMailSpot specifically, the same loop works against the public REST API at /api/v1, and an embeddable widget is available when you want a disposable inbox inside your own page. TempMailSpot can also send a reply (gated by a CAPTCHA), which most receive-only tools cannot, and it exports any message to PDF, JSON, or EML.

When you need a local SMTP sink instead (Mailpit vs MailHog)

A hosted temp inbox is the wrong tool when the mail you want to inspect is sent by your own application in development or CI, especially if it never leaves the machine. For that, run a local SMTP capture server: point your app's SMTP config at it, and every message your code sends is trapped and viewable instead of going anywhere real.

The maintained, current choice is Mailpit, "a small, fast, low memory, zero-dependency, multi-platform email testing tool & API for developers." It runs a local SMTP server and a web UI, and exposes an API so tests can read captured mail. By default it listens for SMTP on port 1025 and serves its web UI on port 8025 — deliberately the same defaults as the older MailHog, which makes it a near drop-in replacement.

# Point your app at SMTP localhost:1025; open the web UI at http://localhost:8025
docker run -d --name mailpit -p 1025:1025 -p 8025:8025 axllent/mailpit

A word on the tool you will still see recommended in older posts. MailHog was the long-time default, but it is effectively unmaintained: its most recent GitHub release is v1.0.1, published August 11, 2018, with nothing newer since. The community has said so directly: issue #442 is titled "THIS PROJECT IS DEAD!" and notes "more than 200 pull requests are unattended." (You may see secondary blogs claim MailHog's last release was 2020; the primary releases page shows 2018. Use the 2018 date.) Mailpit was written specifically as a modern, actively maintained successor that keeps MailHog's ports, so migrating is usually a one-line change.

The dividing line is simple:

Use a hosted temp inbox (Mail.tm, TempMailSpot, etc.)Use a local SMTP sink (Mailpit)
Testing against a real external service you do not controlInspecting mail your own app sends
You need a real, routable addressThe recipient address is irrelevant
Manual checks, staging, third-party signup flowsCI, localhost, no outbound delivery
Verifying the full DNS/SMTP round tripCapturing and asserting on outbound content

Patterns and pitfalls for reliable email tests

A few habits separate email tests that are trustworthy from ones the team learns to ignore.

Use a unique recipient per run

Reusing one address across runs invites "account already exists" failures and cross-test contamination. Generate a fresh inbox per test, or (when you control the receiving domain in development) use plus-addressing (signup+{runId}@yourdomain.test) so each run is isolated and searchable. With a hosted disposable provider, provision a new address rather than re-polling a shared one.

Match on content, not arrival alone

Asserting only that "an email arrived" passes when the wrong email arrives. Match on subject and sender, then parse and assert on the body: the verification code is well-formed, the reset link points at the right host and is single-use, the unsubscribe link is present. Extract and follow the link in the same test to prove the round trip, not just the send.

Mind provider caps and rate limits

The limits documented above are test-design constraints, not trivia. Maildrop's 10-message ceiling, Guerrilla Mail's 20-per-check, and Mail.tm's 8 QPS/IP each shape how you poll and clean up. Fetch-and-delete on high-volume runs so a capped inbox does not silently drop the message you are waiting for, and never share one IP's rate budget across many parallel jobs.

Keep test mail out of production

Disposable addresses are only one guard. The structural one is environment-based routing: in any non-production environment, intercept outbound mail (a local SMTP sink) or redirect every recipient to a controlled address, so a stray test can never reach a real user. That belongs in your mail configuration, not in individual tests.

Do not test deliverability with disposable mail

It bears repeating because it is a frequent mistake: a disposable inbox tells you nothing about whether production mail lands in a real user's inbox. For inbox-placement and reputation, use real mailboxes you control or a dedicated deliverability service, as covered in the email delivery testing guide.

For a developer, temporary email is the fast path to exercising the receive side of a real email flow: provision an address, run signup or verification or password reset, read and assert on what arrives, discard. Reach for a hosted temp-mail API (Mail.tm and similar are free and key-less) when you are testing an external service and need a real routable inbox, and a local SMTP sink like Mailpit when you only need to inspect mail your own app sends. Remember the two boundaries that trip people up: real forms reject known disposable domains via public blocklists like the one PyPI uses, and disposable mail measures function, never deliverability.

To test a flow by hand right now, open a disposable inbox — no account, mail appears on its own within seconds, with a 10-minute timer you can extend and PDF, JSON, or EML export for anything you need to keep.

Frequently Asked Questions

Sources

  1. disposable-email-domains (GitHub)disposable-email-domains: a list of disposable and temporary email address domains (2014)
  2. IETF / RFC EditorRFC 5321: Simple Mail Transfer Protocol (2008)
  3. Mail.tmTemp Mail API - Mail.tm (2026)
  4. Guerrilla MailGuerrilla Mail JSON API (2024)
  5. MaildropHow It Works | Maildrop (2024)
  6. Temp Mail (temp-mail.org)Temporary Disposable Email API - Temp Mail (2026)
  7. Kaspersky SecurelistSpam and phishing in 2024 (2025)
  8. Anti-Phishing Working GroupPhishing Activity Trends Report Q3 2024 (2024)

Recommended Privacy Tools

Expert-vetted tools to enhance your online privacy and security

NordVPN

VPN

Encrypted tunneling across thousands of servers with an audited no-logs policy. For private browsing on untrusted networks.

Learn More

ExpressVPN

VPN

Consistently fast servers in 90 plus countries, an audited no-logs policy, and a clean app on every platform.

Learn More

Surfshark

VPN

Unlimited devices on one plan, with ad and tracker blocking built in. The budget pick that does not feel budget.

Learn More

Related Articles