unsent
unsent.dev

SMTP

A comprehensive guide to integrate Unsent with SMTP across different languages and frameworks

This guide explains how to integrate Unsent using SMTP. This is useful if you want to use existing email libraries or legacy systems that support SMTP.

Prerequisites

Before you begin, ensure you have the following:

  • Unsent API Key: You can generate one in your Unsent dashboard.
  • Verified Domain: You need a verified domain to send emails. Set this up in the Domains section.

SMTP Credentials

To configure your SMTP client, use the following settings:

  • Host: smtp.unsent.dev
  • Port: 465 (SSL), 587 (TLS), 2465 (SSL Alternative), or 2587 (TLS Alternative)
  • Username: unsent
  • Password: YOUR-API-KEY (Replace this with your actual API key)

Node.js / TypeScript

Using Nodemailer

Nodemailer is the most popular email library for Node.js and TypeScript applications.

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

// Create a transporter object using the default SMTP transport
const transporter = nodemailer.createTransport({
  host: "smtp.unsent.dev",
  port: 465,
  secure: true, // Use true for port 465, false for other ports
  auth: {
    user: "unsent",
    pass: process.env.UNSENT_API_KEY!, // Your API Key from environment variable
  },
});

// Define email options
const mailOptions = {
  to: "recipient@example.com",
  from: "hello@yourdomain.com", // Must be from a verified domain
  subject: "Welcome to Unsent",
  html: "<h1>Hello!</h1><p>This email was sent via Unsent SMTP.</p>",
  text: "Hello! This email was sent via Unsent SMTP.",
};

// Send the email
async function sendEmail() {
  try {
    const info = await transporter.sendMail(mailOptions);
    console.log("Email sent successfully:", info.messageId);
    return info;
  } catch (error) {
    console.error("Error sending email:", error);
    throw error;
  }
}

export { sendEmail };

Next.js API Route Example

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

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

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

  try {
    const info = await transporter.sendMail({
      from: "noreply@yourdomain.com",
      to,
      subject,
      html,
    });

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

Python

Using smtplib (Built-in)

Python's built-in smtplib module provides SMTP support out of the box.

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")  # Your API key

def send_email(to_email, subject, html_content, text_content):
    # Create message
    message = MIMEMultipart("alternative")
    message["Subject"] = subject
    message["From"] = "hello@yourdomain.com"  # Must be from verified domain
    message["To"] = to_email

    # Add text and HTML parts
    text_part = MIMEText(text_content, "plain")
    html_part = MIMEText(html_content, "html")
    message.attach(text_part)
    message.attach(html_part)

    # Send email
    try:
        with smtplib.SMTP_SSL(SMTP_HOST, SMTP_PORT) as server:
            server.login(SMTP_USER, SMTP_PASSWORD)
            server.send_message(message)
            print(f"Email sent successfully to {to_email}")
    except Exception as e:
        print(f"Error sending email: {e}")
        raise

# Example usage
if __name__ == "__main__":
    send_email(
        to_email="recipient@example.com",
        subject="Hello from Unsent",
        html_content="<h1>Welcome!</h1><p>This is sent via Unsent SMTP.</p>",
        text_content="Welcome! This is sent via Unsent SMTP."
    )

Using 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'] = 'noreply@yourdomain.com'

mail = Mail(app)

@app.route('/send-email')
def send_email():
    msg = Message(
        subject="Hello from Flask",
        recipients=["recipient@example.com"],
        html="<h1>Hello!</h1><p>Sent via Unsent SMTP</p>",
        body="Hello! Sent via Unsent SMTP"
    )
    
    try:
        mail.send(msg)
        return {"success": True, "message": "Email sent"}
    except Exception as e:
        return {"success": False, "error": str(e)}, 500

PHP

Using PHPMailer

PHPMailer is the most popular email library for PHP.

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

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

function sendEmail($to, $subject, $htmlBody, $textBody) {
    $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'); // Your API key
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
        $mail->Port       = 465;

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

        // Content
        $mail->isHTML(true);
        $mail->Subject = $subject;
        $mail->Body    = $htmlBody;
        $mail->AltBody = $textBody;

        $mail->send();
        echo 'Email sent successfully';
        return true;
    } catch (Exception $e) {
        echo "Email could not be sent. Error: {$mail->ErrorInfo}";
        return false;
    }
}

// Example usage
sendEmail(
    'recipient@example.com',
    'Hello from Unsent',
    '<h1>Welcome!</h1><p>This is sent via Unsent SMTP.</p>',
    'Welcome! This is sent via Unsent SMTP.'
);
?>

Using Laravel Mail

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 $user;

    public function __construct($user)
    {
        $this->user = $user;
    }

    public function build()
    {
        return $this->from('hello@yourdomain.com')
                    ->subject('Welcome to Our Platform')
                    ->view('emails.welcome');
    }
}
config/mail.php
<?php

return [
    'default' => env('MAIL_MAILER', 'smtp'),

    'mailers' => [
        'smtp' => [
            'transport' => 'smtp',
            'host' => env('MAIL_HOST', 'smtp.unsent.dev'),
            'port' => env('MAIL_PORT', 465),
            'encryption' => env('MAIL_ENCRYPTION', 'ssl'),
            'username' => env('MAIL_USERNAME', 'unsent'),
            'password' => env('MAIL_PASSWORD'),
        ],
    ],

    'from' => [
        'address' => env('MAIL_FROM_ADDRESS', 'hello@yourdomain.com'),
        'name' => env('MAIL_FROM_NAME', 'Your App'),
    ],
];
.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"

Go

Using net/smtp (Built-in)

main.go
package main

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

func sendEmail(to, subject, htmlBody, textBody string) error {
    // SMTP configuration
    smtpHost := "smtp.unsent.dev"
    smtpPort := "465"
    smtpUser := "unsent"
    smtpPass := os.Getenv("UNSENT_API_KEY")

    // Sender and recipient
    from := "hello@yourdomain.com"

    // Message
    message := []byte(
        "From: " + from + "\r\n" +
        "To: " + to + "\r\n" +
        "Subject: " + subject + "\r\n" +
        "MIME-Version: 1.0\r\n" +
        "Content-Type: text/html; charset=UTF-8\r\n" +
        "\r\n" +
        htmlBody + "\r\n",
    )

    // Authentication
    auth := smtp.PlainAuth("", smtpUser, smtpPass, smtpHost)

    // Send email
    err := smtp.SendMail(
        smtpHost+":"+smtpPort,
        auth,
        from,
        []string{to},
        message,
    )

    if err != nil {
        return fmt.Errorf("failed to send email: %w", err)
    }

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

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

Ruby

Using Mail Gem

send_email.rb
require 'mail'

# Configure Mail
Mail.defaults do
  delivery_method :smtp, {
    address:              'smtp.unsent.dev',
    port:                 465,
    user_name:            'unsent',
    password:             ENV['UNSENT_API_KEY'],
    authentication:       'plain',
    enable_starttls_auto: true,
    ssl:                  true
  }
end

def send_email(to, subject, html_body, text_body)
  mail = Mail.new do
    from     'hello@yourdomain.com'
    to       to
    subject  subject

    text_part do
      body text_body
    end

    html_part do
      content_type 'text/html; charset=UTF-8'
      body html_body
    end
  end

  mail.deliver!
  puts "Email sent successfully to #{to}"
rescue => e
  puts "Error sending email: #{e.message}"
  raise
end

# Example usage
send_email(
  'recipient@example.com',
  'Hello from Unsent',
  '<h1>Welcome!</h1><p>This is sent via Unsent SMTP.</p>',
  'Welcome! This is sent via Unsent SMTP.'
)

Using Rails Action 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
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
  }
end

Testing Your Integration

After setting up SMTP, you can test your integration by:

  1. Send a test email using your configured SMTP client
  2. Check the Unsent dashboard at app.unsent.dev to verify the email was sent
  3. Monitor delivery status and any potential errors in the dashboard

Make sure your sending domain is verified before sending emails. Unverified domains will result in failed deliveries.

Common Issues

Authentication Failed

If you receive authentication errors, verify that:

  • You're using unsent as the username (not your email)
  • Your API key is correct and active
  • You haven't accidentally included extra whitespace in your credentials

Connection Timeout

If you experience connection timeouts:

  • Try using alternative ports (2465 for SSL or 2587 for TLS)
  • Check if your hosting provider blocks standard SMTP ports
  • Verify your firewall settings allow outbound SMTP connections

Emails Not Delivering

If emails aren't being delivered:

  • Ensure your sending domain is verified in the Unsent dashboard
  • Check that the "from" address uses your verified domain
  • Review the email logs in your Unsent dashboard for specific error messages