Send emails over SMTP

If your framework already sends mail through SMTP, point it here and nothing else has to change.

Host smtp.mailstein.com
Port 2525
Encryption STARTTLS
Username anything — it is ignored
Password your mailstein API key

Messages are parsed and handed to the same pipeline as POST /v1/emails, so domain verification, suppression and quotas all apply, and the message shows up in your dashboard alongside everything else.

Nodemailer

import nodemailer from "nodemailer";

const transport = nodemailer.createTransport({
  host: "smtp.mailstein.com",
  port: 2525,
  secure: false, // upgraded by STARTTLS
  auth: { user: "mailstein", pass: process.env.MAILSTEIN_API_KEY },
});

await transport.sendMail({
  from: "hello@yourdomain.com",
  to: "someone@example.com",
  subject: "Hello",
  html: "<p>It works.</p>",
});

Django

EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = "smtp.mailstein.com"
EMAIL_PORT = 2525
EMAIL_USE_TLS = True
EMAIL_HOST_USER = "mailstein"
EMAIL_HOST_PASSWORD = os.environ["MAILSTEIN_API_KEY"]
DEFAULT_FROM_EMAIL = "hello@yourdomain.com"

Rails

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address: "smtp.mailstein.com",
  port: 2525,
  user_name: "mailstein",
  password: ENV["MAILSTEIN_API_KEY"],
  authentication: :plain,
  enable_starttls_auto: true,
}

WordPress, Metabase, Retool, and anything else with an SMTP box

Same four values. Host smtp.mailstein.com, port 2525, STARTTLS on, password is the API key.

Why 2525 and not 587

587 is the port most tools default to, and it is not served yet. 2525 is the usual alternate and is what to use today. Many hosting providers also block outbound 25 and 587 from application servers, which is a second reason 2525 is often the one that works.

What SMTP does not give you

Idempotency keys, tags, scheduling, templates by id, and batch sending are all API-only. SMTP is the compatibility path — use it to get an existing application sending without touching its code, and use the API when you want the features.

Something here wrong or missing? It is generated from the running API — tell us and we will fix the source.