SendPigeon Documentation
Everything you need to send transactional emails. SDKs for Node.js, Python, Go, PHP and REST API.
SMTP Relay
Send emails via standard SMTP. Works with any language, framework, or legacy system.
Standard SMTP. Connect to smtp.sendpigeon.dev:587 with STARTTLS and your API key. Same deliverability, same tracking, same pipeline as the REST API.
Connection Details
| Host | smtp.sendpigeon.dev |
| Port | 587 |
| Encryption | STARTTLS (required) |
| Username | apikey |
| Password | Your API key (sk_live_...) |
| Max message | 25 MB |
Quick Test
Verify your setup with swaks (Swiss Army Knife for SMTP):
swaks --server smtp.sendpigeon.dev:587 --tls \ --auth-user apikey --auth-password sk_live_xxx \ --from hello@yourdomain.com --to test@example.com \ --header "Subject: Test SMTP" --body "Hello from SMTP"Node.js (Nodemailer)
import nodemailer from "nodemailer"; const transport = nodemailer.createTransport({ host: "smtp.sendpigeon.dev", port: 587, secure: false, auth: { user: "apikey", pass: process.env.SENDPIGEON_API_KEY, },}); await transport.sendMail({ from: "Acme <hello@yourdomain.com>", to: "user@example.com", subject: "Welcome!", html: "<h1>Hello from SMTP</h1>",});Python
import smtplibfrom email.mime.text import MIMEText msg = MIMEText("<h1>Hello from SMTP</h1>", "html")msg["From"] = "Acme <hello@yourdomain.com>"msg["To"] = "user@example.com"msg["Subject"] = "Welcome!" with smtplib.SMTP("smtp.sendpigeon.dev", 587) as server: server.starttls() server.login("apikey", "sk_live_xxx") server.send_message(msg)Ruby (Action Mailer)
# config/environments/production.rbconfig.action_mailer.smtp_settings = { address: "smtp.sendpigeon.dev", port: 587, user_name: "apikey", password: ENV["SENDPIGEON_API_KEY"], authentication: :plain, enable_starttls_auto: true,}PHP (Laravel)
# .envMAIL_MAILER=smtpMAIL_HOST=smtp.sendpigeon.devMAIL_PORT=587MAIL_USERNAME=apikeyMAIL_PASSWORD=sk_live_xxxMAIL_ENCRYPTION=tlsGo
package main import ( "net/smtp") func main() { auth := smtp.PlainAuth("", "apikey", "sk_live_xxx", "smtp.sendpigeon.dev") msg := []byte("From: hello@yourdomain.com\r\n" + "To: user@example.com\r\n" + "Subject: Welcome!\r\n" + "Content-Type: text/html\r\n" + "\r\n" + "<h1>Hello from SMTP</h1>") smtp.SendMail("smtp.sendpigeon.dev:587", auth, "hello@yourdomain.com", []string{"user@example.com"}, msg)}Tracking via Headers
Control open and click tracking per-message using custom headers. These headers are stripped before delivery.
| Header | Values | Default |
|---|---|---|
| X-SP-Track-Opens | true / false | No tracking |
| X-SP-Track-Clicks | true / false | No tracking |
Custom Headers
The same custom headers allowed via REST API work over SMTP. X-* headers and List-* headers are forwarded. Standard envelope headers (From, To, Subject, etc.) are handled automatically.
Same pipeline. SMTP messages go through the same validation, domain verification, rate limiting, and delivery pipeline as the REST API. Logs, webhooks, and analytics work identically.