Skip to content

SMTP Relay

Use PostStack as an SMTP relay for applications that cannot use the REST API. All features including tracking, webhooks, and analytics work with SMTP.

TLS required. The relay accepts implicit TLS (SSL on connect) on port 465, and both implicit TLS and STARTTLS on port 587 (RFC 8314). For implicit TLS set secure: true in nodemailer or use Python's smtplib.SMTP_SSL. A connection that neither starts with TLS nor upgrades with STARTTLS is closed before it can authenticate.

Connection Details

SettingValue
Hostsmtp.poststack.dev
Port587 (STARTTLS or implicit TLS) or 465 (implicit TLS)
EncryptionTLS 1.2 / 1.3 required — on connect, or via STARTTLS before AUTH
Usernamepoststack (any value is accepted when the password is an API key)
PasswordYour API key (sk_live_...)

Use a live key, not a test key. A sk_test_... key authenticates over SMTP just fine and the server answers 250, but the message is simulated — it is recorded and marked delivered without ever being handed to a mail server, so nothing reaches the recipient. The 250 reply says so, and the email shows a Test mode badge in the dashboard. See Test mode.

Mailbox users can also authenticate with their email address and mailbox password instead of an API key. See the Mailboxes docs for email client setup.

Attachments travel over SMTP as normal MIME parts and are subject to the same limits as the API: up to 10 files, 10MB per file and 25MB per message, measured on the file rather than on its encoded form. Inline images referenced from the HTML with cid: stay inline. See Sending emails.

How your message is processed

PostStack is a submission relay, not a byte-for-byte forwarder. Your message is parsed into its parts — addresses, subject, HTML and text bodies, attachments — recorded as an email you can see in the dashboard, and then re-composed on the way out. That is what makes tracking, templates, suppression, webhooks and analytics work over SMTP, and it has three consequences worth knowing before you point a mail server at us.

An existing DKIM signature is not preserved. If your server already signs its own mail (Mailcow, Postfix with OpenDKIM, Microsoft 365), that signature is not carried through. A DKIM signature covers the exact bytes of the message, and re-composing changes them, so passing the original header on would only produce a signature that fails verification. PostStack signs the outgoing message itself, using the key it generated for your verified domain — so it still leaves with a valid d=yourdomain.com signature that aligns for DMARC. Relaying through us replaces your signature; it does not leave the message unsigned. There is currently no passthrough mode that keeps your own signature.

Only your X- headers are carried. Headers beginning with X- are passed through to the recipient (the X-PostStack-* ones below are read as instructions and removed), and In-Reply-To / References are kept so replies thread. Other headers from your original message are not carried, and PostStack sets its own Message-ID and Date.

Tracking is optional. Open tracking adds a pixel and click tracking rewrites links, and both modify your HTML. Turn either off per domain — see Domains — and your body is delivered as you wrote it.

Custom Headers

Add PostStack-specific headers to your SMTP messages to use advanced features:

HeaderDescription
X-PostStack-Idempotency-KeyPrevent duplicate sends with a unique idempotency key
X-PostStack-TagsComma-separated tags for categorizing emails
X-PostStack-Template-IdUse a published template by ID
X-PostStack-VariablesJSON-encoded template variables
X-PostStack-ScheduleISO 8601 datetime to schedule delivery (same as the API's scheduled_at)

Node.js (Nodemailer)

Use Nodemailer with PostStack SMTP credentials. Note secure: true on port 465 (implicit TLS). On 587 use secure: false, requireTLS: true to upgrade with STARTTLS instead.

typescript
import nodemailer from 'nodemailer';

const transporter = nodemailer.createTransport({
  host: 'smtp.poststack.dev',
  port: 465,
  secure: true, // implicit TLS (port 587: secure: false, requireTLS: true)
  auth: {
    user: 'poststack',
    pass: 'sk_live_...',
  },
});

await transporter.sendMail({
  from: 'you@yourdomain.com',
  to: 'user@example.com',
  subject: 'Hello from PostStack SMTP',
  html: '<p>Sent via SMTP relay!</p>',
  headers: {
    'X-PostStack-Tags': 'welcome,onboarding',
  },
});

Python (smtplib)

Use smtplib.SMTP_SSL for implicit TLS on 465 (or smtplib.SMTP(host, 587) followed by starttls()):

python
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

msg = MIMEMultipart("alternative")
msg["From"] = "you@yourdomain.com"
msg["To"] = "user@example.com"
msg["Subject"] = "Hello from PostStack SMTP"
msg["X-PostStack-Tags"] = "welcome,onboarding"

html = "<p>Sent via SMTP relay!</p>"
msg.attach(MIMEText(html, "html"))

with smtplib.SMTP_SSL("smtp.poststack.dev", 465) as server:
    server.login("poststack", "sk_live_...")
    server.sendmail(
        "you@yourdomain.com",
        "user@example.com",
        msg.as_string(),
    )

Using Templates via SMTP

Reference templates and pass variables through custom SMTP headers:

typescript
await transporter.sendMail({
  from: 'you@yourdomain.com',
  to: 'user@example.com',
  subject: '', // Overridden by template
  text: '',    // Overridden by template
  headers: {
    'X-PostStack-Template-Id': 'tpl_abc123def456ghi789',
    'X-PostStack-Variables': JSON.stringify({
      first_name: 'Alice',
      company_name: 'Acme Inc',
    }),
  },
});

Related

SMTP relay overviewUsing PostStack from WordPress, Laravel, Rails and any SMTP client.