SMTP Relay
SMTP Relay
Send email through Postscale using any standard SMTP client — Outlook, Thunderbird, sendmail, or application libraries like Nodemailer, PHPMailer, and Python's smtplib. Authenticate with your API key as the password.
Server Settings
| Setting | Value |
|---|---|
| Host | smtp.postscale.io |
| Port | 587 |
| Encryption | STARTTLS |
| Username | postscale |
| Password | Your API key |
The same API key you use for the REST API works for SMTP. Generate one from the API Keys page.
Available Ports
| Port | Protocol | When to use |
|---|---|---|
| 587 | STARTTLS | Recommended for most clients |
| 465 | Implicit TLS | For clients that require direct SSL |
| 2525 | STARTTLS | When your ISP blocks port 587 |
| 2587 | STARTTLS | When your ISP blocks port 587 |
All connections are encrypted. Authentication is required before sending.
Authentication
The username is always postscale (case-insensitive). The password is your Postscale API key.
Supported SASL mechanisms:
- PLAIN — single-step, supported by all SMTP clients
- LOGIN — two-step challenge-response, for older clients
Invalid or revoked API keys are rejected at login time with 535 Authentication failed.
Quick Start
Command Line (swaks)
swaks --server smtp.postscale.io:587 --tls \
--auth PLAIN --auth-user postscale --auth-password "YOUR_API_KEY" \
--from sender@yourdomain.com --to recipient@example.com \
--header "Subject: Hello from Postscale" \
--body "Sent via SMTP relay!"
Python
import smtplib
from email.mime.text import MIMEText
msg = MIMEText("Hello from Postscale SMTP!")
msg["Subject"] = "Test email"
msg["From"] = "sender@yourdomain.com"
msg["To"] = "recipient@example.com"
with smtplib.SMTP("smtp.postscale.io", 587) as server:
server.starttls()
server.login("postscale", "YOUR_API_KEY")
server.send_message(msg)
Node.js (Nodemailer)
const nodemailer = require("nodemailer");
const transporter = nodemailer.createTransport({
host: "smtp.postscale.io",
port: 587,
secure: false, // STARTTLS
auth: {
user: "postscale",
pass: "YOUR_API_KEY",
},
});
await transporter.sendMail({
from: "sender@yourdomain.com",
to: "recipient@example.com",
subject: "Test email",
text: "Hello from Postscale SMTP!",
});
Go
package main
import "net/smtp"
func main() {
auth := smtp.PlainAuth("", "postscale", "YOUR_API_KEY", "smtp.postscale.io")
msg := []byte("From: sender@yourdomain.com\r\n" +
"To: recipient@example.com\r\n" +
"Subject: Test email\r\n" +
"\r\n" +
"Hello from Postscale SMTP!")
smtp.SendMail(
"smtp.postscale.io:587",
auth,
"sender@yourdomain.com",
[]string{"recipient@example.com"},
msg,
)
}
PHP (PHPMailer)
<?php
use PHPMailer\PHPMailer\PHPMailer;
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = 'smtp.postscale.io';
$mail->SMTPAuth = true;
$mail->Username = 'postscale';
$mail->Password = 'YOUR_API_KEY';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;
$mail->setFrom('sender@yourdomain.com');
$mail->addAddress('recipient@example.com');
$mail->Subject = 'Test email';
$mail->Body = 'Hello from Postscale SMTP!';
$mail->send();
Ruby (Mail gem)
require 'mail'
Mail.defaults do
delivery_method :smtp,
address: 'smtp.postscale.io',
port: 587,
user_name: 'postscale',
password: 'YOUR_API_KEY',
authentication: :plain,
enable_starttls_auto: true
end
Mail.deliver do
from 'sender@yourdomain.com'
to 'recipient@example.com'
subject 'Test email'
body 'Hello from Postscale SMTP!'
end
Custom Headers
Add special headers to your SMTP messages to attach tags and metadata. These are extracted by the relay and are not delivered to the recipient.
X-Postscale-Tags
Comma-separated list of tags to apply to the message.
X-Postscale-Tags: welcome, onboarding, en
X-Postscale-Metadata
JSON object of key-value string pairs to attach to the message.
X-Postscale-Metadata: {"user_id": "123", "campaign": "welcome"}
Example with Custom Headers
swaks --server smtp.postscale.io:587 --tls \
--auth PLAIN --auth-user postscale --auth-password "YOUR_API_KEY" \
--from sender@yourdomain.com --to recipient@example.com \
--header "Subject: Welcome" \
--header "X-Postscale-Tags: welcome, onboarding" \
--header 'X-Postscale-Metadata: {"user_id": "42", "campaign": "launch"}' \
--body "Welcome to the platform!"
Any non-standard header that isn't a Postscale header (like X-My-Header) is passed through to the API as a raw header and included in the delivered message.
Limits
| Limit | Value |
|---|---|
| Max message size | 50 MB |
| Max recipients/msg | 100 |
| Connection timeout | 60s |
Rate limits match your plan's API rate limits. Exceeding them returns 452 Rate limit exceeded.
Error Reference
| SMTP Response | Cause |
|---|---|
535 Invalid username, use "postscale" | Username is not postscale |
535 Authentication failed | API key is invalid or revoked |
451 Authentication service unavailable | Relay cannot reach the Postscale API |
451 API unavailable | API unreachable during send |
554 Failed to parse message | Malformed MIME message |
452 Rate limit exceeded, try again later | Too many requests for this API key |
550 All recipients suppressed | Every recipient is on a suppression list |
502 Authentication required | Client sent MAIL FROM without logging in |
Prerequisites
Before sending via SMTP, your sending domain must be verified:
- Add the domain in the dashboard under Domains
- Add the required DNS records (SPF, DKIM, DMARC)
- Click Verify Domain
See Domain Setup for the full DNS configuration guide, or the Setup Checklist to verify your complete configuration.
FAQ
Can I use Outlook, Thunderbird, or other desktop email clients?
Yes. Add smtp.postscale.io as your outgoing SMTP server with port 587, STARTTLS, username postscale, and your API key as the password.
What if my ISP blocks port 587?
Use port 2525 or 2587 instead. They use the same STARTTLS protocol.
Do I need a separate API key for SMTP?
No. The same API key works for both SMTP and the REST API.
Is CRAM-MD5 supported?
No. Use PLAIN or LOGIN instead — both are safe over TLS.
What happens to X-Postscale- headers?*
They are extracted by the SMTP relay and mapped to API fields. They are not included in the delivered message.