SMTP Relay
Send emails through Veil Mail using standard SMTP. Integrate with any language or framework that supports SMTP without using our REST API or SDK.
Overview
The Veil Mail SMTP relay accepts email submissions via standard SMTP protocol. All emails sent through SMTP relay benefit from the same features as the REST API:
- PII scanning - Automatic detection and handling of sensitive data
- Delivery tracking - Opens, clicks, bounces, and complaints
- Dedicated IP support - Route through your IP pools
- Webhook events - Same event notifications as the REST API
SMTP Configuration
Use these settings to configure any SMTP client:
| Setting | Value |
|---|---|
| SMTP Host | smtp.veilmail.xyz |
| Port (STARTTLS) | 587 |
| Port (TLS/SSL) | 465 |
| Authentication | PLAIN or LOGIN |
| Username | Your SMTP credential username |
| Password | Your SMTP credential password |
Create SMTP Credentials
Create a set of SMTP credentials to authenticate with the relay. The password is returned only once when the credential is created -- store it securely.
POST /v1/smtp/credentialscreate-credential.ts
const credential = await client.smtp.createCredential({
name: 'Production SMTP',
});
// Store these securely - password is shown only once!
console.log(credential.username); // 'veil_smtp_a1b2c3d4e5f6...'
console.log(credential.password); // 'abc123def456...'
console.log(credential.smtpHost); // 'smtp.veilmail.xyz'
console.log(credential.smtpPort); // 587
console.log(credential.smtpPortTls); // 465Store the Password Securely
The password is only returned once. If you lose it, you will need to rotate the credential to generate a new password.
Code Examples
Node.js (Nodemailer)
nodemailer.ts
import nodemailer from 'nodemailer';
const transporter = nodemailer.createTransport({
host: 'smtp.veilmail.xyz',
port: 587,
secure: false, // STARTTLS
auth: {
user: 'veil_smtp_a1b2c3d4e5f6...',
pass: 'your-smtp-password',
},
});
await transporter.sendMail({
from: '"My App" <hello@example.com>',
to: 'user@example.com',
subject: 'Hello from SMTP',
html: '<h1>Welcome!</h1><p>Sent via Veil Mail SMTP relay.</p>',
});Python (smtplib)
smtp_send.py
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
msg = MIMEMultipart("alternative")
msg["Subject"] = "Hello from SMTP"
msg["From"] = "hello@example.com"
msg["To"] = "user@example.com"
html = "<h1>Welcome!</h1><p>Sent via Veil Mail SMTP relay.</p>"
msg.attach(MIMEText(html, "html"))
with smtplib.SMTP("smtp.veilmail.xyz", 587) as server:
server.starttls()
server.login("veil_smtp_a1b2c3d4e5f6...", "your-smtp-password")
server.sendmail(msg["From"], msg["To"], msg.as_string())Ruby (Net::SMTP)
smtp_send.rb
require 'net/smtp'
message = <<~MSG
From: hello@example.com
To: user@example.com
Subject: Hello from SMTP
Content-Type: text/html
<h1>Welcome!</h1><p>Sent via Veil Mail SMTP relay.</p>
MSG
Net::SMTP.start(
'smtp.veilmail.xyz', 587,
'example.com', # HELO domain
'veil_smtp_a1b2c3d4e5f6...', # username
'your-smtp-password', # password
:plain
) do |smtp|
smtp.send_message(message, 'hello@example.com', 'user@example.com')
endPHP (PHPMailer)
smtp_send.php
use PHPMailer\PHPMailer\PHPMailer;
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = 'smtp.veilmail.xyz';
$mail->SMTPAuth = true;
$mail->Username = 'veil_smtp_a1b2c3d4e5f6...';
$mail->Password = 'your-smtp-password';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;
$mail->setFrom('hello@example.com', 'My App');
$mail->addAddress('user@example.com');
$mail->isHTML(true);
$mail->Subject = 'Hello from SMTP';
$mail->Body = '<h1>Welcome!</h1><p>Sent via Veil Mail SMTP relay.</p>';
$mail->send();Go (net/smtp)
smtp_send.go
package main
import (
"net/smtp"
)
func main() {
auth := smtp.PlainAuth("",
"veil_smtp_a1b2c3d4e5f6...",
"your-smtp-password",
"smtp.veilmail.xyz",
)
msg := []byte("From: hello@example.com\r\n" +
"To: user@example.com\r\n" +
"Subject: Hello from SMTP\r\n" +
"Content-Type: text/html\r\n" +
"\r\n" +
"<h1>Welcome!</h1><p>Sent via Veil Mail SMTP relay.</p>")
smtp.SendMail(
"smtp.veilmail.xyz:587",
auth,
"hello@example.com",
[]string{"user@example.com"},
msg,
)
}Manage Credentials
List Credentials
GET /v1/smtp/credentialslist-credentials.ts
const { data: credentials } = await client.smtp.listCredentials();
for (const cred of credentials) {
console.log(`${cred.name}: ${cred.username} (${cred.status})`);
}Rotate Password
Generate a new password for an existing credential. The old password is immediately invalidated.
POST /v1/smtp/credentials/:id/rotaterotate-password.ts
const result = await client.smtp.rotatePassword('cred_xxxxx');
// Store the new password - shown only once!
console.log(result.password); // new passwordRevoke Credential
DELETE /v1/smtp/credentials/:idrevoke-credential.ts
await client.smtp.revokeCredential('cred_xxxxx');Security Best Practices
- Use environment variables - Never hardcode SMTP credentials in source code. Store them in environment variables or a secrets manager.
- Create separate credentials - Use different credentials for different environments (development, staging, production) and services.
- Rotate regularly - Rotate SMTP passwords periodically and after any security incident.
- Always use TLS - Connect on port 587 with STARTTLS or port 465 with implicit TLS. Never send credentials in plain text.
- Revoke unused credentials - Remove credentials that are no longer needed to reduce your attack surface.
Python SDK
smtp_credentials.py
# Create SMTP credentials
credential = client.smtp.create_credential(name="Production SMTP")
print(f"Username: {credential['username']}")
print(f"Password: {credential['password']}") # Store securely!
# Rotate password
rotated = client.smtp.rotate_password(credential["id"])
print(f"New password: {rotated['password']}")
# List credentials
credentials = client.smtp.list_credentials()
for cred in credentials["data"]:
print(f"{cred['name']}: {cred['status']}")
# Revoke
client.smtp.revoke_credential(credential["id"])