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:

SettingValue
SMTP Hostsmtp.veilmail.xyz
Port (STARTTLS)587
Port (TLS/SSL)465
AuthenticationPLAIN or LOGIN
UsernameYour SMTP credential username
PasswordYour 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/credentials
create-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); // 465

Store 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')
end

PHP (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/credentials
list-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/rotate
rotate-password.ts
const result = await client.smtp.rotatePassword('cred_xxxxx');

// Store the new password - shown only once!
console.log(result.password); // new password

Revoke Credential

DELETE /v1/smtp/credentials/:id
revoke-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"])