Tutorials

Generate Disposable Email Inboxes for Test Runs

| | 9 min read
Generate Disposable Email Inboxes for Test Runs
Generate Disposable Email Inboxes for Test Runs

Email is the slow, messy dependency that makes automated test runs flaky. A signup test might pass locally but fail in CI because the inbox already contains an old verification link, delivery is delayed, or parsing the email body is brittle. The fix is simple: generate a fresh disposable email inbox for every test run, then assert against the messages you receive in a structured format.

This guide shows a practical, repeatable approach for creating disposable inboxes programmatically, collecting emails reliably, and using them in QA automation and LLM-driven agents.

What “disposable email inboxes” means for test runs

For testing, a disposable inbox is not just a random email address. It is an inbox you can:

  • Create on demand (per run, per spec, or per user)
  • Read automatically (without a human opening a UI)
  • Correlate to a specific test context (run ID, scenario ID)
  • Delete or ignore after the run finishes

This matters because many “temporary email” sites are built for humans, not automation. They often have rate limits, no API, unreliable delivery, and no safe way to integrate into CI.

💡 Stop dealing with flaky email tests

Mailhook eliminates the headaches of unreliable temporary email providers. Create disposable inboxes programmatically, receive emails as structured JSON, and build rock-solid test automation. Start testing reliably → or See the API docs →

Mailhook is built specifically for automation and agents: you create disposable inboxes via API, then receive inbound emails as structured JSON, either by polling or real-time webhooks.

Common test-run scenarios that need a fresh inbox

Disposable inboxes pay off anywhere your product sends emails and expects the user to act:

  • Signup verification (OTP codes, verification links)
  • Password resets
  • Magic links (passwordless login)
  • Invitations (workspace invites, teammate onboarding)
  • Email change confirmations
  • Inbound email parsing (support replies, inbound routing, reply-to handling)
  • Agent workflows where an LLM must “receive an email” and extract a token

If you build automation that touches outreach or lead handling, you will also want disposable inboxes in staging to test inbound flows without polluting real mailboxes. For example, teams building Instagram lead pipelines like Orsay often need to validate follow-up and response loops end-to-end across environments.

What to look for in a disposable inbox API (QA + agent edition)

Not all disposable email providers are automation-friendly. Here is a practical checklist and how it maps to Mailhook’s capabilities.

Requirement for test runs Why it matters in CI and agents What to use in Mailhook
Programmatic inbox creation You need one inbox per run, not a shared mailbox Disposable inbox creation via API
Structured messages Tests should assert on fields, not regex HTML Receive emails as JSON
Real-time delivery signals Avoid long sleeps and flaky polling loops Webhook notifications
Polling fallback Some CI setups cannot accept inbound webhooks Polling API for emails
Security controls Don’t trust unsigned callbacks in automation Signed payloads
Domain options Shared domains are quick, custom domains give control Instant shared domains + custom domain support
Batch-friendly processing Many tests generate many emails Batch email processing

The “one inbox per test run” pattern

The simplest reliable pattern is:

  1. Generate a new inbox at the start of the run
  2. Use that address in your app under test (signup, reset, invite)
  3. Wait for the email (webhook-first, polling as a fallback)
  4. Assert on the JSON (subject, recipient, links, codes)
  5. End the run and throw the inbox away

A key idea: treat the inbox like a test fixture. Your app should never send test emails to a shared address that accumulates history.

A simple flow diagram showing a CI test runner creating a disposable inbox via an API, the app sending an email to that address, and the inbox forwarding the received email as structured JSON to either a webhook endpoint or a polling client for assertions.

Step-by-step: generate a disposable inbox and assert on the email

Because endpoint shapes can vary over time, the most robust way to implement is:

  • Use the Mailhook API to create an inbox and obtain an email address
  • Use either webhook delivery or polling to fetch received messages
  • Keep your test assertions focused on stable fields (recipient, subject, extracted URL/token)

For the most up-to-date interface details, keep the official reference handy: Mailhook llms.txt.

1) Create an inbox (at test start)

Create the inbox as part of your test setup and store:

  • The generated email address (to feed into your UI/API)
  • The inbox identifier (to fetch messages later)

Implementation tip: name or tag inboxes using a deterministic run key (for example run_2026_01_17_build_1842). Even if you do not rely on server-side tags, keeping this value in your test logs makes debugging much easier.

2) Trigger the email from your app

Run the action you want to test:

  • Call your signup endpoint with the disposable email
  • Or complete the UI signup flow in Playwright/Cypress

At this point, the email should be sent by your app to the new address.

3) Receive the email: webhook-first or polling

Webhook approach (recommended for speed and reliability)

  • Your test harness exposes a callback endpoint (or a small local server)
  • Mailhook posts inbound email events to your webhook
  • You unblock the test as soon as the event arrives

For security, verify signed payloads before accepting the event (Mailhook supports signed payloads).

Polling approach (best when webhooks are inconvenient)

  • After triggering the email, poll the inbox for messages
  • Stop when you receive the expected message or you hit a timeout

In CI, polling is often simpler to wire up, but webhooks usually reduce total runtime and flakiness.

4) Assert against JSON fields, not email HTML

The exact JSON shape depends on the provider, but a structured email payload typically includes fields like:

  • Sender and recipient addresses
  • Subject
  • Text body and/or HTML body
  • Headers
  • Attachments (if present)

Testing tip: prefer assertions like:

  • “recipient equals the generated address”
  • “subject contains ‘Verify your email’”
  • “body contains a URL with path /verify

Then parse the verification link or OTP in a targeted way. Avoid brittle snapshots of the entire HTML.

Making email-based tests less flaky

Most failures come from timing and ambiguity. These practices harden your suite.

Use correlation, not guessing

If your app might send multiple emails, include a correlation cue in the request so you can identify the right message quickly. Examples:

  • A unique run ID embedded in the signup name (if your template includes it)
  • A distinct subject prefix in test environment
  • A distinct email address per scenario (best option)

The cleanest approach remains: one inbox per scenario.

Replace sleeps with explicit waits

Instead of sleep(10), do:

  • Webhook: wait on a promise/event for up to N seconds
  • Polling: poll with a short interval and an overall timeout

A practical starting point in CI is a 30 to 60 second max wait, with 1 to 2 second polling intervals. Tune based on your email provider and environment.

Assert the minimum that proves correctness

Email templates change often. Your test should validate the behavior, not the copywriting.

Good assertions:

  • Verification link exists and is valid
  • Reset token matches expected format
  • Recipient address is correct

Risky assertions:

  • Exact HTML markup
  • Full paragraph text

Shared domains vs custom domains for testing

Mailhook supports instant shared domains and custom domain support. Which should you use?

Shared domains are ideal when:

  • You want the fastest setup
  • You are running internal QA and CI where domain branding does not matter
  • You do not need domain-level deliverability tuning

Custom domains are ideal when:

  • You want realistic staging environments (for example, test.yourcompany.com)
  • You need more control over how mail is sent/received in your ecosystem
  • You want to mirror production assumptions closely

In practice, many teams start with shared domains for speed, then add a custom domain once the tests are stable.

Using disposable inboxes with LLM agents

LLM agents frequently need to complete workflows that involve email:

  • Create a trial account
  • Wait for verification
  • Extract a code or link
  • Continue the workflow

A reliable agent pattern is:

  • Tool: create_inbox() returns { inbox_id, email_address }
  • Tool: wait_for_email(inbox_id, filter) returns the next matching email JSON
  • Agent logic: extract verification_link or OTP and proceed

When you use webhook delivery, you can also push messages into your agent’s event queue as soon as they arrive, reducing latency and eliminating unnecessary polling cycles.

💡 Build smarter AI agents that handle email workflows

Give your LLM agents the ability to create accounts, receive verification emails, and extract tokens automatically. With Mailhook’s API-first approach, agents get structured JSON responses perfect for autonomous workflows. Explore AI agent use cases → or Start building →

If you are implementing agent tools, keep the interface small and deterministic. Agents perform better when the tool returns structured data, which is exactly the point of receiving emails as JSON.

Implementation notes for teams shipping CI at scale

A few operational practices help once you have many concurrent test runs:

  • Parallelism: generate one inbox per worker to avoid collisions.
  • Isolation: never reuse inboxes across runs, even if you “clean” them.
  • Debuggability: log the generated email address and inbox ID for each run.
  • Security: verify webhook signatures, treat email content as untrusted input.
  • Throughput: if you process many emails at once, prefer batch-friendly fetching and parsing to reduce overhead.

Get started with Mailhook

If your tests or agents depend on email, disposable inboxes are one of the highest ROI changes you can make for reliability. Mailhook is designed for exactly this: programmable inbox creation via API, inbound emails delivered as structured JSON, real-time webhooks, polling fallback, signed payloads, and support for both shared and custom domains.

Use the canonical feature and integration reference here: Mailhook llms.txt.

Then explore the platform at Mailhook to start generating disposable email inboxes for your next test run.