14-day free trial on every plan

Test every email your app sends. In Playwright, Cypress and CI.

Every test run gets its own inbox. Signup links, OTP codes and receipts land in it within seconds — parsed, extracted and ready to assert on. Nothing is ever delivered to a real person.

  • Inbox in 30 seconds
  • Cancel anytime
  • No servers or DNS
signup.spec.ts● running…
const inbox = await mailqa.inboxes.create({ name: 'signup' });
const link = await mailqa.waitForLink({ inbox: inbox.id });
await page.goto(link);   // no sleep(). no flake.
ci-run-4187@acme.mailqa.iolive
waiting for mail…
Verify your email addressjust nowAcme <noreply@acme.dev>link extractedSPF ✓ DKIM ✓
Your login code is 481-33014s agoAcme <otp@acme.dev>code: 481330
runs in your test suite
  • Playwright
  • Cypress
  • Jest
  • Vitest
  • GitHub Actions
  • any CI
captures from any mailer
  • SendGrid
  • Postmark
  • Amazon SES
  • Resend
  • Mailgun
  • Nodemailer
  • your own SMTP

// how it works

Your app sends. mailQA catches. Your test asserts.

Three steps and no infrastructure. Point your app at mailQA once, and every email it sends becomes data your tests — and your team — can read.

ci-4187 · new inboxAPI or UI
Create your inbox with API or UIci-4187@acme.mailqa.ioCreate inbox
await mailer.send({
  to: inbox.address,
  subject: 'Verify your email' })
→ smtp.mailqa.io:587 · 250 OK
@ci-4187@acme.mailqa.iomailQA
waiting for mail…
Verify your emailnow
Acme <noreply@acme.dev>
link extractedSPF ✓ DKIM ✓ DMARC ✓html · text · raw .eml
captured · never delivered
signup.spec.tsidle
const link = await
  mailqa.waitForLink({ inbox })
await page.goto(link)
✓ received in 412ms
✓ page.goto(link)
✓ account verified
also live in the dashboard
01Create an inbox from the API or the dashboard; your app sends to it as it does today.
02mailQA catches it, parses it, and extracts links, codes and auth verdicts.
03Your test resolves the moment it lands. No sleep(), no polling.

// why mailqa

Built for the way email actually breaks tests.

every flow that ends in an emailEmail verificationOTP / one-time codesPassword resetMagic linksSignupReceipts & invoices

Stop manually checking test inboxes.

Create an inbox from your test and automate the entire email workflow. The first 14 days are free.

Start your free trial

// in your test suite

Fits inside the test you already have.

One import. The test creates its own inbox, drives your app normally, and gets the email back as data — no shared mailbox, no sleep(), no message left over from the last run.

  • A fresh address per run — nothing left over from last time.
  • One call to wait; the link, the code and the parsed body come back typed.
  • Creating an inbox is idempotent, so a CI fixture re-runs cleanly.
Read the SDK reference →
signup.spec.ts — Playwright@mailqa/client
const inbox = await mailqa.inboxes.create({ name: 'signup' });

await page.goto('https://example.com/signup');
await page.fill('[name="email"]', inbox.address);
await page.click('button[type="submit"]');

const link = await mailqa.waitForLink({ inbox: inbox.id });

await page.goto(link);
await expect(page.getByText('Email verified')).toBeVisible();

// the dashboard

Manual QA gets the same mail, live.

Messages appear the instant they arrive — no refresh. Keep sending through SendGrid, Postmark, SES or Resend with your real templates, point the recipient at anyone@your-org.mailqa.io, and every message lands here exactly as production would send it.

mailqa.io/acme/inboxes
ci-run-4187live
Your invoice for Septemberjust now
Acme Billing <billing@acme.dev>
via SendGrid1 attachment
Verify your email address2m
Acme <noreply@acme.dev>
via Postmarklink
Your login code is 481-3309m
Acme <otp@acme.dev>
via SEScode 481330
You've been invited to Acme1h
Acme <team@acme.dev>
via Resendlink
HTMLTextRaw .emlHeadersAuth
Verify your email addressfrom noreply@acme.dev · to ci-4187@acme.mailqa.io
SPF passDKIM passDMARC passvia Postmark
Confirm your emailThanks for signing up. Click below to verify your address and finish creating your account.Confirm email →sent with your real template — nothing changed
extracted: acme.dev/verify?t=9f2…copy
new message in staging · Your invoice for September
works unchanged withSendGridPostmarkAmazon SESResendMailgunyour own SMTP

// pricing

Start free. Keep it only if it earns its place.

Every plan starts with a 14-day free trial. Cancel before it ends and you pay nothing — and there is no mail infrastructure to tear down either.

Basic
$4.99per month
14-day free trial
  • 10 inboxes
  • 1,000 messages / month
  • SMTP sink + real MX address
  • 7-day retention
  • 2 team members
Start free trial
MOST POPULARPro
$9.99per month
14-day free trial
  • 50 inboxes
  • 50,000 messages / month
  • Your own receiving domain
  • Catch-all addresses
  • 30-day retention
  • 10 team members
Start free trial
Team
$19.99per month
14-day free trial
  • 500 inboxes
  • 500,000 messages / month
  • Your own receiving domain
  • Catch-all addresses
  • 90-day retention
  • 100 team members
Start free trial
  • Nothing is ever delivered to a real person — there is no forwarding path.
  • Your card is taken at signup and first charged when the 14-day trial ends.
  • Change or cancel from the dashboard, any time. Limits follow the moment you do.
  • Payments are processed by Stripe; the card number never touches mailQA.

Compare every feature, plan by plan →

14-day free trial · cancel anytime

Your first inbox is 30 seconds away.

No servers. No DNS. No mail infrastructure to run — and nothing ever delivered by mistake.