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.
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
- Open your namespace in the dashboard and go to Settings → SMTP.
- Copy the credentials into your app's SMTP settings.
- 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.