unsent
unsent.dev

SMTP Server

Send emails through Unsent using SMTP - the universal email protocol supported by all major email libraries and frameworks

Unsent provides a fully-featured SMTP server that allows you to send emails using the standard SMTP protocol. This is perfect for integrating with existing applications, legacy systems, or any email library that supports SMTP.

Why Use SMTP?

Universal Compatibility

Works with any programming language or framework that supports SMTP - no SDK required.

Drop-in Replacement

Migrate from other email services by simply changing your SMTP credentials.

Legacy System Support

Integrate with older applications that only support email via SMTP.

Enterprise Security

Full TLS/SSL support with secure authentication using your API key.

Features

Unsent's SMTP server provides comprehensive email sending capabilities:

  • Standard SMTP Protocol: Full RFC 5321 compliance
  • Multiple Security Options: STARTTLS on ports 587/2587 and implicit SSL/TLS on ports 465/2465
  • Authentication: Secure auth using your Unsent API key
  • Multipart Messages: Send HTML and plain text versions in one email
  • Custom Headers: Add custom email headers including Reply-To
  • Large Message Support: Up to 10MB per email
  • Reliable Delivery: Built on Unsent's proven email infrastructure

Prerequisites

Before you begin, ensure you have:

SMTP Connection Details

Configure your SMTP client with these settings:

SettingValue
Hostsmtp.unsent.dev
Ports465 (SSL/TLS), 587 (STARTTLS), 2465 (SSL Alternative), 2587 (TLS Alternative)
Usernameunsent
PasswordYour Unsent API Key (starts with un_)
AuthenticationPLAIN or LOGIN
EncryptionSSL/TLS (port 465, 2465) or STARTTLS (port 587, 2587)

Port Selection Guide

Recommended Ports:

  • Port 465: Use this for implicit SSL/TLS (most secure, recommended for production)
  • Port 587: Use this for STARTTLS (widely supported)
  • Ports 2465/2587: Alternative ports if your hosting provider blocks standard SMTP ports

Quick Start Examples

Node.js with Nodemailer

Nodemailer is the most popular email library for Node.js.

npm install nodemailer
lib/email.ts
import nodemailer from "nodemailer";

// Create reusable transporter
const transporter = nodemailer.createTransport({
  host: "smtp.unsent.dev",
  port: 465,
  secure: true, // true for port 465, false for 587
  auth: {
    user: "unsent",
    pass: process.env.UNSENT_API_KEY, // Your API key
  },
});

// Send email
async function sendEmail() {
  const info = await transporter.sendMail({
    from: '"Your Name" <hello@yourdomain.com>',
    to: "recipient@example.com",
    subject: "Welcome to Unsent",
    text: "Hello! This email was sent via Unsent SMTP.",
    html: "<h1>Hello!</h1><p>This email was sent via Unsent SMTP.</p>",
  });

  console.log("Message sent:", info.messageId);
}

sendEmail().catch(console.error);

Python with smtplib

Python's built-in smtplib module provides SMTP support.

send_email.py
import smtplib
import os
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

# SMTP configuration
smtp_host = "smtp.unsent.dev"
smtp_port = 465
smtp_user = "unsent"
smtp_password = os.getenv("UNSENT_API_KEY")

# Create message
message = MIMEMultipart("alternative")
message["Subject"] = "Welcome to Unsent"
message["From"] = "hello@yourdomain.com"
message["To"] = "recipient@example.com"

# Add text and HTML parts
text_part = MIMEText("Hello! This email was sent via Unsent SMTP.", "plain")
html_part = MIMEText("<h1>Hello!</h1><p>This email was sent via Unsent SMTP.</p>", "html")
message.attach(text_part)
message.attach(html_part)

# Send email
with smtplib.SMTP_SSL(smtp_host, smtp_port) as server:
    server.login(smtp_user, smtp_password)
    server.send_message(message)
    print("Email sent successfully!")

PHP with PHPMailer

composer require phpmailer/phpmailer
send_email.php
<?php
require 'vendor/autoload.php';

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

$mail = new PHPMailer(true);

try {
    // Server settings
    $mail->isSMTP();
    $mail->Host = 'smtp.unsent.dev';
    $mail->SMTPAuth = true;
    $mail->Username = 'unsent';
    $mail->Password = getenv('UNSENT_API_KEY');
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
    $mail->Port = 465;

    // Recipients
    $mail->setFrom('hello@yourdomain.com', 'Your Name');
    $mail->addAddress('recipient@example.com');

    // Content
    $mail->isHTML(true);
    $mail->Subject = 'Welcome to Unsent';
    $mail->Body = '<h1>Hello!</h1><p>This email was sent via Unsent SMTP.</p>';
    $mail->AltBody = 'Hello! This email was sent via Unsent SMTP.';

    $mail->send();
    echo 'Email sent successfully!';
} catch (Exception $e) {
    echo "Error: {$mail->ErrorInfo}";
}
?>

Framework Integrations

Next.js

Create an API route to send emails:

app/api/send-email/route.ts
import { NextResponse } from "next/server";
import nodemailer from "nodemailer";

const transporter = nodemailer.createTransport({
  host: "smtp.unsent.dev",
  port: 465,
  secure: true,
  auth: {
    user: "unsent",
    pass: process.env.UNSENT_API_KEY!,
  },
});

export async function POST(request: Request) {
  const { to, subject, html, text } = await request.json();

  try {
    const info = await transporter.sendMail({
      from: process.env.FROM_EMAIL,
      to,
      subject,
      html,
      text,
    });

    return NextResponse.json({ 
      success: true, 
      messageId: info.messageId 
    });
  } catch (error) {
    console.error("Email error:", error);
    return NextResponse.json(
      { success: false, error: "Failed to send email" },
      { status: 500 }
    );
  }
}

Laravel

Update your .env file:

.env
MAIL_MAILER=smtp
MAIL_HOST=smtp.unsent.dev
MAIL_PORT=465
MAIL_USERNAME=unsent
MAIL_PASSWORD=your_unsent_api_key
MAIL_ENCRYPTION=ssl
MAIL_FROM_ADDRESS=hello@yourdomain.com
MAIL_FROM_NAME="Your App"

Create a Mailable:

app/Mail/WelcomeEmail.php
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class WelcomeEmail extends Mailable
{
    use Queueable, SerializesModels;

    public function __construct(public $user) {}

    public function build()
    {
        return $this->subject('Welcome to Our Platform')
                    ->view('emails.welcome');
    }
}

Send the email:

use App\Mail\WelcomeEmail;
use Illuminate\Support\Facades\Mail;

Mail::to($user->email)->send(new WelcomeEmail($user));

Flask (Python)

pip install Flask-Mail
app.py
from flask import Flask
from flask_mail import Mail, Message
import os

app = Flask(__name__)

# Configure Flask-Mail
app.config['MAIL_SERVER'] = 'smtp.unsent.dev'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USERNAME'] = 'unsent'
app.config['MAIL_PASSWORD'] = os.getenv('UNSENT_API_KEY')
app.config['MAIL_DEFAULT_SENDER'] = 'hello@yourdomain.com'

mail = Mail(app)

@app.route('/send-email')
def send_email():
    msg = Message(
        subject="Welcome to Our Platform",
        recipients=["recipient@example.com"],
        html="<h1>Hello!</h1><p>Welcome aboard!</p>",
        body="Hello! Welcome aboard!"
    )
    
    mail.send(msg)
    return {"success": True}

Ruby on Rails

Configure Action Mailer in config/environments/production.rb:

config/environments/production.rb
Rails.application.configure do
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    address: 'smtp.unsent.dev',
    port: 465,
    user_name: 'unsent',
    password: ENV['UNSENT_API_KEY'],
    authentication: 'plain',
    enable_starttls_auto: true,
    ssl: true
  }
  
  config.action_mailer.default_url_options = { host: 'yourdomain.com' }
end

Create a mailer:

app/mailers/user_mailer.rb
class UserMailer < ApplicationMailer
  default from: 'hello@yourdomain.com'

  def welcome_email(user)
    @user = user
    mail(to: @user.email, subject: 'Welcome to Our Platform')
  end
end

Go

main.go
package main

import (
    "crypto/tls"
    "fmt"
    "net/smtp"
    "os"
)

func sendEmail(to, subject, body string) error {
    from := "hello@yourdomain.com"
    password := os.Getenv("UNSENT_API_KEY")
    
    // Setup message
    msg := []byte("To: " + to + "\r\n" +
        "From: " + from + "\r\n" +
        "Subject: " + subject + "\r\n" +
        "Content-Type: text/html; charset=UTF-8\r\n" +
        "\r\n" + body + "\r\n")

    // SMTP auth
    auth := smtp.PlainAuth("", "unsent", password, "smtp.unsent.dev")

    // TLS config
    tlsConfig := &tls.Config{
        ServerName: "smtp.unsent.dev",
    }

    // Connect to server
    conn, err := tls.Dial("tcp", "smtp.unsent.dev:465", tlsConfig)
    if err != nil {
        return err
    }
    defer conn.Close()

    client, err := smtp.NewClient(conn, "smtp.unsent.dev")
    if err != nil {
        return err
    }
    defer client.Quit()

    // Authenticate
    if err := client.Auth(auth); err != nil {
        return err
    }

    // Send email
    if err := client.Mail(from); err != nil {
        return err
    }
    if err := client.Rcpt(to); err != nil {
        return err
    }

    w, err := client.Data()
    if err != nil {
        return err
    }
    _, err = w.Write(msg)
    if err != nil {
        return err
    }
    err = w.Close()
    if err != nil {
        return err
    }

    fmt.Println("Email sent successfully!")
    return nil
}

func main() {
    err := sendEmail(
        "recipient@example.com",
        "Welcome to Unsent",
        "<h1>Hello!</h1><p>Welcome aboard!</p>",
    )
    if err != nil {
        fmt.Printf("Error: %v\n", err)
    }
}

Advanced Usage

Sending with Custom Headers

Add custom headers like Reply-To, CC, BCC:

advanced-email.ts
await transporter.sendMail({
  from: '"Your Company" <hello@yourdomain.com>',
  to: "recipient@example.com",
  cc: "manager@yourdomain.com",
  bcc: "archive@yourdomain.com",
  replyTo: "support@yourdomain.com",
  subject: "Your Order Confirmation",
  html: "<h1>Order Confirmed</h1>",
  text: "Order Confirmed",
  headers: {
    'X-Custom-Header': 'CustomValue',
    'X-Priority': '1',
  },
});

Sending to Multiple Recipients

bulk-email.ts
// Multiple recipients as comma-separated string
await transporter.sendMail({
  from: "hello@yourdomain.com",
  to: "user1@example.com, user2@example.com, user3@example.com",
  subject: "Team Update",
  html: "<p>Hello team!</p>",
});

// Or as an array
await transporter.sendMail({
  from: "hello@yourdomain.com",
  to: ["user1@example.com", "user2@example.com"],
  subject: "Team Update",
  html: "<p>Hello team!</p>",
});

HTML Emails with Inline Images

html-with-images.ts
await transporter.sendMail({
  from: "hello@yourdomain.com",
  to: "recipient@example.com",
  subject: "Welcome!",
  html: `
    <html>
      <body>
        <h1>Welcome to Unsent!</h1>
        <img src="cid:logo" alt="Logo" />
        <p>We're glad to have you.</p>
      </body>
    </html>
  `,
  attachments: [{
    filename: 'logo.png',
    path: '/path/to/logo.png',
    cid: 'logo' // Same as referenced in img src
  }]
});

Using Templates

Combine SMTP with your favorite templating engine:

templated-email.ts
import Handlebars from "handlebars";
import fs from "fs";

// Load and compile template
const templateSource = fs.readFileSync("./templates/welcome.hbs", "utf8");
const template = Handlebars.compile(templateSource);

// Render with data
const html = template({
  name: "John Doe",
  activationLink: "https://yourapp.com/activate/abc123"
});

// Send
await transporter.sendMail({
  from: "hello@yourdomain.com",
  to: "john@example.com",
  subject: "Activate Your Account",
  html,
});

Testing Your Integration

1. Send a Test Email

Use your configured SMTP client to send a test email to yourself.

2. Verify in Dashboard

Check the Unsent dashboard to confirm the email was received and processed.

3. Monitor Delivery

Track delivery status, opens, and clicks in real-time through the dashboard.

Command-Line Testing with swaks

For quick testing, use swaks:

swaks --to recipient@example.com \
  --from hello@yourdomain.com \
  --server smtp.unsent.dev \
  --port 465 \
  --auth LOGIN \
  --auth-user unsent \
  --auth-password your_api_key \
  --tls

Important: Your sending domain must be verified in the Unsent dashboard before you can send emails. Unverified domains will result in failed deliveries.

Security Best Practices

1. Protect Your API Key

  • Never commit API keys to version control
  • Use environment variables to store credentials
  • Rotate keys regularly in the dashboard
.env (example)
UNSENT_API_KEY=un_your_secret_key_here
FROM_EMAIL=hello@yourdomain.com

2. Use TLS/SSL

Always use encrypted connections:

  • Port 465 with SSL/TLS (secure from start)
  • Port 587 with STARTTLS (upgrade to secure)
  • Never send credentials over unencrypted connections

3. Verify Sender Domains

Only send from verified domains to ensure deliverability and prevent spoofing.

4. Implement Rate Limiting

Implement client-side rate limiting to stay within your plan limits and avoid overwhelming recipients.

Troubleshooting

Authentication Failed

Symptoms: 535 Authentication failed or similar error

Solutions:

  • Verify you're using unsent as the username (not your email address)
  • Ensure your API key is correct and hasn't been revoked
  • Check for extra whitespace in your credentials
  • Confirm your API key is active in the dashboard

Connection Timeout or Refused

Symptoms: ETIMEDOUT or ECONNREFUSED

Solutions:

  • Check if your hosting provider blocks SMTP ports (try alternative ports 2465/2587)
  • Verify firewall settings allow outbound SMTP connections
  • Test connectivity: telnet smtp.unsent.dev 465
  • Try a different port (587 with STARTTLS)

TLS/SSL Errors

Symptoms: SSL routines or certificate errors

Solutions:

  • Ensure your SMTP library supports TLS/SSL
  • Update SSL libraries to the latest version
  • For port 465, enable secure: true in your configuration
  • For port 587, enable STARTTLS

Emails Not Delivering

Symptoms: Email sent successfully but not delivered

Solutions:

  • Verify your sending domain in the Unsent dashboard
  • Ensure the "from" address matches your verified domain
  • Check the email logs in the dashboard for specific errors
  • Review spam folder in recipient's inbox
  • Verify you haven't exceeded your plan limits

"Must issue STARTTLS command first"

Symptoms: Authentication rejected on port 587

Solutions:

  • Enable STARTTLS in your SMTP client configuration
  • Or switch to port 465 with implicit SSL/TLS

Large Email Rejected

Symptoms: 552 Message size exceeds maximum

Solutions:

  • Reduce email size (current limit: 10MB)
  • Compress or resize images
  • Host large files externally and link to them
  • Consider splitting into multiple emails

Monitoring and Analytics

Email Dashboard

Monitor all SMTP-sent emails in your Unsent dashboard:

  • Real-time delivery status
  • Bounce and complaint tracking
  • Open and click analytics
  • Detailed error logs

Email Events

Track email lifecycle events:

  • Queued: Email accepted by SMTP server
  • Sent: Successfully delivered to recipient's mail server
  • Delivered: Confirmed delivery
  • Bounced: Delivery failed (see reason in logs)
  • Opened: Recipient opened the email (if tracking enabled)
  • Clicked: Recipient clicked a link

API Access

Retrieve email data programmatically using the Unsent REST API:

curl https://api.unsent.dev/v1/emails \
  -H "Authorization: Bearer YOUR_API_KEY"

Migration Guide

From SendGrid

Replace SendGrid SMTP credentials:

- host: "smtp.sendgrid.net"
+ host: "smtp.unsent.dev"
- port: 587
+ port: 465
- user: "apikey"
+ user: "unsent"
- pass: "SG.xxx"
+ pass: "un_xxx"
+ secure: true

From Mailgun

Replace Mailgun SMTP credentials:

- host: "smtp.mailgun.org"
+ host: "smtp.unsent.dev"
- port: 587
+ port: 465
- user: "postmaster@your-domain.mailgun.org"
+ user: "unsent"
- pass: "mailgun-password"
+ pass: "un_xxx"
+ secure: true

From AWS SES

Replace AWS SES SMTP credentials:

- host: "email-smtp.us-east-1.amazonaws.com"
+ host: "smtp.unsent.dev"
- port: 587
+ port: 465
- user: "AKIAIOSFODNN7EXAMPLE"
+ user: "unsent"
- pass: "aws-ses-smtp-password"
+ pass: "un_xxx"
+ secure: true

After migration, verify your domain in the Unsent dashboard and update any hardcoded email addresses to use your verified domain.

Need Help?

Documentation: unsent.dev/docs
Report Issues: Contact support with your email logs

Pro Tip: For maximum deliverability, combine SMTP with proper email authentication (SPF, DKIM, DMARC) and maintain a good sender reputation.