October 26, 2026

Introducing virtual SMTP

Mailisk can now work as a virtual SMTP server, a catch-all for every email your app sends. Put your namespace's SMTP credentials into your app, staging environment or CI, and every email the app sends lands in Mailisk. That includes emails to real addresses like jane@gmail.com. None of them get delivered.

Your app sends to jane@gmail.com. The email goes to Mailisk and stops there. Jane's real inbox never receives it.

Real customers in staging

Staging databases fill up with real addresses. Someone copies production data to reproduce a bug, or a seed script pulls in last year's customer export. Then a test run sends password resets and invoices to all of them.

The usual fixes are rewriting every recipient before sending, or keeping a list of addresses that are safe to email. Both work until someone adds a new email type and forgets the check.

With virtual SMTP the recipient stops mattering. If an email went through Mailisk SMTP, it stops at Mailisk.

Set it up

  1. Open your namespace in the dashboard and go to Settings → SMTP.
  2. Copy the credentials into your app's SMTP settings.
  3. Send an email from your app. It shows up in the namespace inbox.
Setting Value
Host smtp.mailisk.net
Port 587 with STARTTLS, or 465 with TLS
Username {namespace}@mailisk.net
Password Shown on the SMTP tab

Anything that sends over SMTP works: Nodemailer, Django, Rails Action Mailer, Laravel, Spring, or a Postfix relay.

Where captured emails go

Emails to outside addresses, like jane@gmail.com, land in the namespace you logged in with. Emails to your Mailisk addresses go to their own namespace, as they always have.

Test against what was captured

Captured emails are regular Mailisk emails. You can open them in the dashboard, search them with the API, wait for them in Cypress or Playwright, and check them with an agent over MCP.

Here's a password reset sent through Nodemailer to an address that looks real, then read back with the Mailisk Node library:

const nodemailer = require('nodemailer');
const { MailiskClient } = require('mailisk');

const namespace = 'example';

const transport = nodemailer.createTransport({
  host: 'smtp.mailisk.net',
  port: 587,
  auth: {
    user: `${namespace}@mailisk.net`,
    pass: process.env.MAILISK_SMTP_PASSWORD,
  },
});

const mailisk = new MailiskClient({ apiKey: process.env.MAILISK_API_KEY });

async function main() {
  await transport.sendMail({
    from: 'no-reply@yourapp.com',
    to: 'jane@gmail.com',
    subject: 'Reset your password',
    text: 'Your reset code is 482913',
  });

  const { data: emails } = await mailisk.searchInbox(namespace, {
    to_addr_prefix: 'jane@gmail.com',
    subject_includes: 'reset',
  });

  console.log(emails[0].text); // Your reset code is 482913
}

main();

The address jane@gmail.com never receives it.

See the SMTP docs for the full reference.

Ready to start testing emails?
Create a free account.

Get started