SMTP
Send through smtp.postfly.app on port 587 with STARTTLS and your API key — for apps and frameworks that speak SMTP.
For apps and frameworks that speak SMTP rather than HTTP. A message submitted over SMTP goes through the same pipeline as POST /v1/emails: the sender domain must be verified, suppressed recipients are refused, and each recipient becomes one message you can follow in the dashboard, the API and webhooks.
Connection settings
| Host | smtp.postfly.app |
|---|---|
| Port | 587 (STARTTLS) |
| Username | apikey (any value is accepted and ignored) |
| Password | your API key, pf_live_… or pf_test_…, with the emails:send scope |
| Encryption | STARTTLS is required; AUTH is refused on an unencrypted session. |
How a message is read
- The
From:header is the sender; its domain must be a verified sender domain of the project. The envelopeMAIL FROMis used only as the bounce address. - Each
RCPT TOaddress becomes one message, up to 50 per SMTP message; a message with more is refused. Subject:, the HTML and text parts andReply-To:are taken as they are. A message with neither an HTML nor a text part is refused.X-Postfly-Tag:sets the message'stag. Other custom headers are dropped; postfly builds the outgoing headers itself.- A message may be up to 25 MB.
Replies & limits
A refusal comes back as an SMTP reply. Validation, domain and suppression problems are permanent 550s. A paused project gets 550 5.7.1 at MAIL FROM. Temporary server faults are 451, safe to retry.
The rate limit is the REST default bucket, 120 per minute per key, counted per recipient, with its own counter separate from the REST API. Past it, further recipients get 452 and a new message gets 451 at MAIL FROM, both saying when to retry; standard clients keep the accepted recipients and retry the rest. The project's daily quota applies too: a message whose recipients would pass it gets 452 after DATA and none of them is queued. The full table is in SMTP replies.
Examples
import nodemailer from 'nodemailer';
const transport = nodemailer.createTransport({
host: 'smtp.postfly.app',
port: 587, // STARTTLS
requireTLS: true,
auth: { user: 'apikey', pass: process.env.POSTFLY_API_KEY },
});
await transport.sendMail({
from: 'Your App <[email protected]>',
to: '[email protected]',
subject: 'Your sign-in code',
text: 'Your code is 381902.',
html: '<p>Your code is <strong>381902</strong>.</p>',
headers: { 'X-Postfly-Tag': 'sign-in' },
});