Sooner or later every team ships an email feature that accidentally mails real customers: a staging copy of production config, a hardcoded address in a loop, a cron job that was supposed to be disabled. Bounced and complaining recipients damage the reputation of your sending domain, and there is no undo button.

An email sandbox removes that risk: it accepts the message over SMTP, stores it and shows it in a dashboard. It never relays, never delivers and accepts any recipient address.

What an email sandbox does (and does not do)

  • Accepts SMTP on the port shown on your inbox page, with the username and password you are given.
  • Parses the raw message: subject, From/To/Cc/Bcc, envelopes, all headers, plain text, HTML and attachments.
  • Keeps it for a configurable retention window and deletes it automatically afterwards.
  • Never sends anything: there is no outbound queue and no relay, so even a real customer address stays inside the sandbox.

Step 1. Create an inbox and copy the credentials

Sign up, create an inbox and open it. You get a host, a port, a username and a password. The password is shown once, so copy it right away; regenerating the credentials invalidates the old password.

Step 2. Point your application at the sandbox

Laravel (.env):

MAIL_MAILER=smtp
MAIL_HOST=sandbox-host
MAIL_PORT=2525
MAIL_USERNAME=inbox_xxxxxxxx
MAIL_PASSWORD=the-password-you-copied
MAIL_ENCRYPTION=null

Python:

import smtplib
from email.message import EmailMessage

msg = EmailMessage()
msg["Subject"] = "Welcome to the sandbox"
msg["From"] = "app@example.com"
msg["To"] = "anyone@example.com"
msg.set_content("Hello from the test flow")

with smtplib.SMTP("sandbox-host", 2525) as server:
    server.login("inbox_xxxxxxxx", "the-password-you-copied")
    server.send_message(msg)

Any SMTP client works the same way: Symfony Mailer, Django, nodemailer, swaks, msmtp, WordPress plugins, or a device that only speaks SMTP.

Step 3. Inspect the result

Send the message and open the inbox: the email appears immediately with the rendered HTML (shown in a sandboxed iframe with scripts disabled), the plain-text part, every header and any attachments. Because nothing was delivered, you can safely send the same flow a hundred times.

Step 4. Check the details that break in production

  • Links and images must be absolute URLs. Relative paths look fine locally and break in a real client.
  • Unsubscribe link and a real physical address are required for bulk mail.
  • Reply-To must be a monitored mailbox, not noreply@.
  • Subject encoding for non-ASCII characters and emoji.
  • Attachments: size limits, correct content types, filenames without spaces.
  • SPF, DKIM and DMARC of your production sender — the sandbox cannot validate these for you, but it does let you see the exact headers your application builds.

Tip: automate it

For integration tests, assert on the captured message instead of a writable mailbox: send through the sandbox, then read the message back (the read-only share link has a JSON export) and check the subject, recipients and body. The test stays fast, deterministic and safe.

Next steps