SMTP for Developers: Send Email from Any Application

A third party SMTP server built for developers. Free sandbox environment, SDKs for every major language, detailed logs, and production-ready infrastructure. Get from zero to sending in under five minutes.

Why Developers Need a Dedicated SMTP Provider

Every application that interacts with users needs to send email. Registration confirmations, password resets, notification digests, invoices, alerts, and reports all depend on reliable email delivery. Yet email is one of the most challenging parts of application infrastructure to get right. The SMTP protocol is decades old, deliverability depends on dozens of factors outside your code, and debugging email issues in production is notoriously difficult.

Using a third party SMTP service like QUEENSMTP eliminates the infrastructure burden so you can focus on building your application. You do not need to configure and maintain a mail server, manage IP reputation, handle bounce processing, implement retry logic, or worry about blacklisting. The SMTP provider handles all of this, exposing a simple interface: connect to our SMTP server, authenticate, send your message, and we deliver it.

A free SMTP server for developers is essential during the development and testing phases. You need to send real emails to verify your templates render correctly, your transactional triggers fire at the right time, and your email content passes spam filters. But you do not want test emails reaching real users or consuming production sending quotas. QUEENSMTP provides a free sandbox environment that captures all outgoing email for inspection without delivering it to recipients, giving you a safe space to develop and test your email functionality.

Beyond the development phase, a dedicated SMTP provider gives you production infrastructure that scales with your application. As your user base grows from hundreds to millions, your email volume grows proportionally. A third party SMTP server for development that also handles production traffic means you never need to migrate your email integration between environments. The same code, configuration, and credentials work from your first test email to your millionth production delivery.

QUEENSMTP Developer Experience

QUEENSMTP is built by developers for developers. Every aspect of the platform is designed to minimize the time between signing up and sending your first email, while providing the depth of functionality and observability that experienced developers expect in production.

Free Sandbox Environment

Every QUEENSMTP account includes a free sandbox that accepts and captures email without delivering it to recipients. The sandbox records every message with full headers, rendered HTML preview, plain text content, and attachment metadata. You can inspect captured emails through the dashboard or retrieve them via API, making it easy to verify your email integration during development. The sandbox supports up to 500 emails per day at no cost, with no credit card required.

Quick Setup

From account creation to sending your first email takes less than five minutes. Sign up, copy your SMTP credentials from the dashboard, configure your application with the host (smtp.queensmtp.com), port (587), and credentials, and send. There is no mandatory domain verification for sandbox mode, no waiting for account approval, and no configuration wizard to click through. Developers who want to test immediately can do so within minutes of creating an account.

SDKs and Libraries

QUEENSMTP provides official SDKs for Node.js, Python, PHP, Ruby, Java, Go, and C#. Each SDK wraps both the SMTP and REST API interfaces with idiomatic code for each language. SDKs handle connection management, authentication, retry logic, and error handling, so you can send email with a single function call. All SDKs are open source, published to their respective package managers (npm, PyPI, Composer, RubyGems, Maven, Go modules, NuGet), and include comprehensive documentation with examples.

SMTP Integration Guide: All Major Languages

Integrating QUEENSMTP into your application is straightforward regardless of your programming language. Below are complete, working code examples for the most popular languages. Each example demonstrates connecting to the SMTP server, authenticating, and sending a basic email.

Node.js (using Nodemailer)

Nodemailer is the standard email library for Node.js applications. Install it with npm install nodemailer and configure the SMTP transport with your QUEENSMTP credentials.

const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
  host: 'smtp.queensmtp.com',
  port: 587,
  secure: false, // STARTTLS
  auth: {
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS
  },
  pool: true,        // enable connection pooling
  maxConnections: 5, // reuse up to 5 connections
  maxMessages: 100   // send 100 messages per connection
});

async function sendEmail(to, subject, html) {
  try {
    const info = await transporter.sendMail({
      from: '"My App" <noreply@example.com>',
      to: to,
      subject: subject,
      html: html,
      // Bulk or marketing mail: set these and we pass them through unchanged.
      // Gmail, Yahoo and Outlook look for List-Unsubscribe, and mail without
      // it is far more likely to be refused as unsolicited.
      headers: {
        'List-Unsubscribe': '<https://example.com/unsubscribe?id=SUBSCRIBER_ID>, <mailto:unsubscribe@example.com>',
        'List-Unsubscribe-Post': 'List-Unsubscribe=One-Click'
      }
    });
    console.log('Message sent:', info.messageId);
    return info;
  } catch (error) {
    console.error('Send failed:', error.message);
    throw error;
  }
}

// Usage
sendEmail('user@example.com', 'Welcome!', '<h1>Welcome to our app</h1>');

Python (using smtplib)

Python's built-in smtplib module provides everything you need to send email through an SMTP server for development and production. No additional packages are required.

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

def send_email(to_addr, subject, html_body):
    msg = MIMEMultipart('alternative')
    msg['From'] = 'noreply@example.com'
    msg['To'] = to_addr
    msg['Subject'] = subject
    msg.attach(MIMEText(html_body, 'html'))

    try:
        with smtplib.SMTP('smtp.queensmtp.com', 587) as server:
            server.starttls()
            server.login(
                os.environ['SMTP_USER'],
                os.environ['SMTP_PASS']
            )
            server.send_message(msg)
            print(f'Email sent to {to_addr}')
    except smtplib.SMTPException as e:
        print(f'Failed to send email: {e}')
        raise

# Usage
send_email('user@example.com', 'Welcome!', '<h1>Welcome</h1>')

PHP (using PHPMailer)

PHPMailer is the most popular email library for PHP. Install it with composer require phpmailer/phpmailer and configure it with your QUEENSMTP SMTP credentials.

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

require 'vendor/autoload.php';

function sendEmail($to, $subject, $htmlBody) {
    $mail = new PHPMailer(true);
    try {
        $mail->isSMTP();
        $mail->Host       = 'smtp.queensmtp.com';
        $mail->SMTPAuth   = true;
        $mail->Username   = getenv('SMTP_USER');
        $mail->Password   = getenv('SMTP_PASS');
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        $mail->Port       = 587;

        $mail->setFrom('noreply@example.com', 'My App');
        $mail->addAddress($to);
        $mail->isHTML(true);
        $mail->Subject = $subject;
        $mail->Body    = $htmlBody;

        $mail->send();
        echo "Email sent to {$to}\n";
    } catch (Exception $e) {
        echo "Send failed: {$mail->ErrorInfo}\n";
        throw $e;
    }
}

// Usage
sendEmail('user@example.com', 'Welcome!', '<h1>Welcome</h1>');

Ruby (using Net::SMTP)

Ruby's standard library includes Net::SMTP for sending email. For production applications, the mail gem provides a higher-level API with MIME support and template rendering.

require 'net/smtp'

def send_email(to, subject, body)
  message = <<~MESSAGE
From: My App <noreply@example.com>
To: #{to}
Subject: #{subject}
MIME-Version: 1.0
Content-Type: text/html; charset=UTF-8

#{body}
  MESSAGE

  Net::SMTP.start(
    'smtp.queensmtp.com', 587,
    'example.com', ENV['SMTP_USER'], ENV['SMTP_PASS'],
    :login
  ) do |smtp|
    smtp.enable_starttls
    smtp.send_message(message, 'noreply@example.com', to)
    puts "Email sent to #{to}"
  end
rescue Net::SMTPError => e
  puts "Send failed: #{e.message}"
  raise
end

# Usage
send_email('user@example.com', 'Welcome!', '<h1>Welcome</h1>')

Go

Go's standard library net/smtp package provides SMTP client functionality. For production use, consider the gomail package which adds connection pooling and MIME support.

package main

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

func sendEmail(to, subject, body string) error {
    from := "noreply@example.com"
    user := os.Getenv("SMTP_USER")
    pass := os.Getenv("SMTP_PASS")

    msg := fmt.Sprintf("From: %s\r\nTo: %s\r\nSubject: %s\r\n"+
        "MIME-Version: 1.0\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n%s",
        from, to, subject, body)

    auth := smtp.PlainAuth("", user, pass, "smtp.queensmtp.com")
    err := smtp.SendMail(
        "smtp.queensmtp.com:587",
        auth,
        from,
        []string{to},
        []byte(msg),
    )
    if err != nil {
        return fmt.Errorf("send failed: %w", err)
    }
    fmt.Printf("Email sent to %s\n", to)
    return nil
}

func main() {
    sendEmail("user@example.com", "Welcome!", "<h1>Welcome</h1>")
}

Java (using Jakarta Mail)

import jakarta.mail.*;
import jakarta.mail.internet.*;
import java.util.Properties;

public class EmailSender {
    private static Session createSession() {
        Properties props = new Properties();
        props.put("mail.smtp.host", "smtp.queensmtp.com");
        props.put("mail.smtp.port", "587");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");

        return Session.getInstance(props, new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(
                    System.getenv("SMTP_USER"),
                    System.getenv("SMTP_PASS")
                );
            }
        });
    }

    public static void sendEmail(String to, String subject, String html)
            throws MessagingException {
        Session session = createSession();
        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress("noreply@example.com"));
        message.setRecipient(Message.RecipientType.TO,
            new InternetAddress(to));
        message.setSubject(subject);
        message.setContent(html, "text/html; charset=UTF-8");
        Transport.send(message);
        System.out.println("Email sent to " + to);
    }
}

C# (.NET)

using System.Net;
using System.Net.Mail;

public class EmailService
{
    private readonly SmtpClient _client;

    public EmailService()
    {
        _client = new SmtpClient("smtp.queensmtp.com", 587)
        {
            Credentials = new NetworkCredential(
                Environment.GetEnvironmentVariable("SMTP_USER"),
                Environment.GetEnvironmentVariable("SMTP_PASS")
            ),
            EnableSsl = true
        };
    }

    public async Task SendEmailAsync(string to, string subject, string html)
    {
        var message = new MailMessage
        {
            From = new MailAddress("noreply@example.com", "My App"),
            Subject = subject,
            Body = html,
            IsBodyHtml = true
        };
        message.To.Add(to);

        try
        {
            await _client.SendMailAsync(message);
            Console.WriteLine($"Email sent to {to}");
        }
        catch (SmtpException ex)
        {
            Console.WriteLine($"Send failed: {ex.Message}");
            throw;
        }
    }
}

REST API vs SMTP Protocol for Developers

QUEENSMTP supports both SMTP protocol and REST API for sending email. Each approach has trade-offs that depend on your application architecture, language ecosystem, and specific requirements.

The SMTP protocol is universally supported. Every programming language has an SMTP library, and most application frameworks include built-in email functionality that speaks SMTP. Using SMTP means you can switch between email providers by changing configuration variables without modifying any code. This portability is valuable for applications that may need to change providers or support self-hosted deployments where customers bring their own SMTP credentials. For a deeper dive into API-based sending, see our Email API documentation.

The REST API provides richer functionality for applications that need it. With the API, you send a message as a JSON request, get back a message id, and query its delivery status by that id. Each request carries one recipient, which gives every message its own delivery status, unsubscribe link and tracking. Event webhooks are in development.

For most applications, the SMTP protocol is the right starting point. It is simpler to configure, universally compatible, and does not create a vendor dependency in your code. Move to the REST API when you want JSON requests, a message id and delivery status per send, and, once they ship, webhooks.

Testing Email in Development

Testing email during development requires capturing outgoing messages without delivering them to real recipients. Sending test emails to real addresses during development risks confusing users, violating anti-spam regulations, and consuming production sending quotas. There are several approaches to safely test email, and the best choice depends on your development workflow.

QUEENSMTP Sandbox Mode

The simplest approach is to use QUEENSMTP's sandbox mode. Configure your development environment with sandbox SMTP credentials, and all outgoing email is captured by QUEENSMTP without being delivered. You can inspect captured messages through the dashboard or API, including rendered HTML, headers, and metadata. This approach requires no additional tools and works with any application that sends email via SMTP.

Local Capture Tools

For offline development or when you want to capture email locally, tools like MailHog and Mailtrap provide a local SMTP server that captures all incoming email and displays it in a web interface. MailHog runs as a single binary or Docker container and is particularly popular for local development because it requires no account or internet connection. Configure your application to send to localhost:1025, and MailHog captures every message for inspection at localhost:8025.

# Run MailHog locally with Docker
docker run -d -p 1025:1025 -p 8025:8025 mailhog/mailhog

# Configure your app SMTP settings for development
SMTP_HOST=localhost
SMTP_PORT=1025
SMTP_USER=       # no auth needed for MailHog
SMTP_PASS=

Catch-All Redirect

Another approach is to configure your application to redirect all outgoing email to a single test address in development. This lets you test email delivery end-to-end while ensuring no test emails reach unintended recipients. Many email libraries support a "redirect all" or "intercept" mode that rewrites the To address before sending.

Environment-Based SMTP Configuration

A well-architected application uses different SMTP configurations for development, staging, and production environments. This ensures test emails never reach real users and production credentials are never exposed in development environments.

# .env.development
SMTP_HOST=localhost          # MailHog or local capture
SMTP_PORT=1025
SMTP_USER=
SMTP_PASS=
SMTP_FROM=dev@example.com

# .env.staging
SMTP_HOST=smtp.queensmtp.com
SMTP_PORT=587
SMTP_USER=staging_user       # Sandbox credentials
SMTP_PASS=staging_pass
SMTP_FROM=staging@example.com

# .env.production
SMTP_HOST=smtp.queensmtp.com
SMTP_PORT=587
SMTP_USER=prod_user          # Production credentials
SMTP_PASS=prod_pass
SMTP_FROM=noreply@example.com

Your application code should read SMTP configuration from environment variables and never hard-code credentials. This pattern works with every deployment platform (Docker, Kubernetes, Heroku, Vercel, AWS, etc.) and every secrets management system (HashiCorp Vault, AWS Secrets Manager, Doppler, etc.). The application behaves identically across environments; only the SMTP destination changes.

For staging environments, use QUEENSMTP sandbox credentials to capture email without delivery. This lets your QA team verify that production email workflows generate the correct messages with the correct content, recipients, and timing, all without any risk of test emails reaching real customers.

Serverless Email Sending

Serverless platforms like AWS Lambda, Vercel Functions, and Cloudflare Workers present unique challenges for SMTP because they are stateless, short-lived, and may not support persistent TCP connections. QUEENSMTP supports both SMTP and REST API, giving you flexibility to choose the best approach for your serverless architecture.

For AWS Lambda functions, the REST API is typically the better choice because HTTP requests complete quickly and do not require maintaining a persistent SMTP connection. Lambda functions have a maximum execution time, and SMTP connections that involve multiple round trips (EHLO, AUTH, MAIL FROM, RCPT TO, DATA, QUIT) consume more of that budget than a single HTTP POST request.

For Vercel and Cloudflare Workers, the REST API is the only practical option because these environments run on edge runtimes that do not support raw TCP connections required by the SMTP protocol. The QUEENSMTP REST API works with the standard fetch API available in all edge runtimes.

// Vercel Edge Function / Cloudflare Worker
export default async function handler(request) {
  const response = await fetch('https://queensmtp.com/v1/send', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.QUEENSMTP_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      from: 'noreply@example.com',
      fromName: 'Example Store',
      replyTo: 'support@example.com',
      to: 'user@example.com',
      subject: 'Your Order Confirmation',
      html: '<h1>Order Confirmed</h1><p>Thank you for your purchase.</p>'
    })
  });

  const result = await response.json();
  return new Response(JSON.stringify(result), { status: 200 });
}

Webhook Integration for Delivery Events (In Development)

Webhooks are being built and are not yet available. This section describes what is coming so you can plan for it; until it ships, read per-message status from GET /v1/messages/:id using the id returned by POST /v1/send, or use the dashboard message log.

When released, QUEENSMTP will POST one JSON event per occurrence to an HTTPS endpoint you register from the dashboard or the API: message.delivered, message.deferred, message.bounced (with an explicit bounceType of hard or soft), message.complained, message.opened, message.clicked, message.unsubscribed and message.rejected. Every event has the same shape: an id to deduplicate on, a type, a created timestamp, and a data object whose messageId is the id you received from /v1/send.

// Express.js endpoint for the upcoming webhook format
const crypto = require('crypto');

app.post('/webhooks/queensmtp', express.raw({ type: 'application/json' }), (req, res) => {
  // X-QueenSMTP-Signature: t=<unix>,v1=<hex HMAC-SHA256 of `${t}.${rawBody}`>
  const sig = Object.fromEntries(String(req.get('X-QueenSMTP-Signature') || '').split(',').map((p) => p.split('=')));
  const expected = crypto.createHmac('sha256', process.env.QUEENSMTP_WEBHOOK_SECRET)
    .update(`${sig.t}.${req.body}`).digest('hex');
  const fresh = Math.abs(Date.now() / 1000 - Number(sig.t)) < 300;
  if (!fresh || !crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig.v1 || ''))) {
    return res.status(401).send('bad signature');
  }

  const event = JSON.parse(req.body);
  switch (event.type) {
    case 'message.bounced':
      if (event.data.bounceType === 'hard') markEmailInvalid(event.data.to);
      break;
    case 'message.complained':
    case 'message.unsubscribed':
      unsubscribeUser(event.data.to);
      break;
  }
  res.status(200).send('OK');
});

Endpoints will need to be idempotent: delivery is retried with backoff for about 24 hours whenever your endpoint does not answer 2xx within 10 seconds, so the same id can arrive more than once. Deduplicate on it.

Headers, Bulk Mail and Unsubscribe over SMTP

The SMTP relay applies the same contract as the REST API. Each message goes to one recipient, may be up to 1 MB with at most two attachments (paid plans), and costs one credit. Your From must be an address on a verified sending domain; its display name, your Reply-To and your Subject are taken from the message. Identity and authentication headers — Message-ID, Date, DKIM, Feedback-ID, Auto-Submitted, X-Mailer — are set by QUEENSMTP and cannot be overridden.

Headers you may set pass through unchanged (up to 25 per message): List-Unsubscribe, List-Unsubscribe-Post, the other List-* headers, Precedence, In-Reply-To, References, Importance, X-Priority and any X- header except the platform's own X-QS-*. Anything else a mail client adds is dropped silently; the message still sends.

Declaring bulk. A List-Unsubscribe header or Precedence: bulk marks a message as marketing: it rides the marketing lane and is stamped Precedence: bulk. Everything else is treated as transactional and stamped Auto-Submitted: auto-generated, so do not add List-Unsubscribe to a password reset or an order confirmation.

Bulk mail must carry an unsubscribe. Send your own List-Unsubscribe together with List-Unsubscribe-Post: List-Unsubscribe=One-Click (RFC 8058) and both pass through untouched; that link is never rewritten by click tracking. Send none and, if the domain has a verified and secured tracking host, QUEENSMTP attaches a one-click unsubscribe hosted on your tracking domain. With neither, the message is refused with 550 [UNSUBSCRIBE_HEADER_REQUIRED]. Either way an opt-out is honoured before the next send to that address.

From: Your Brand <news@yourdomain.com>
To: person@example.com
Subject: September update
List-Unsubscribe: <https://yourdomain.com/unsubscribe?u=42>, <mailto:unsubscribe@yourdomain.com?subject=unsubscribe>
List-Unsubscribe-Post: List-Unsubscribe=One-Click
Precedence: bulk

(body)

In code: Nodemailer headers: { 'List-Unsubscribe': '<https://…>', 'List-Unsubscribe-Post': 'List-Unsubscribe=One-Click' }; PHPMailer $mail->addCustomHeader('List-Unsubscribe', '<https://…>');; Python msg['List-Unsubscribe'] = '<https://…>'.

Tracking is always on for single-recipient HTML mail from a domain with a secured tracking host: an open pixel on every message, links rewritten only on marketing mail (never the unsubscribe link and never transactional links), and the same URIs mirrored into the plain-text part so relay-side filters see matching parts. Your own tracking may stay alongside.

Replies. A refusal is a 550 whose text starts with the reason code in brackets, for example 550 [content_flagged] Rejected: message flagged as likely …; a 451 is temporary and should be retried. Refusals that recorded a strike say so in the same text. Every code is explained on the Developer API page of your dashboard, and every refused message appears in your message log with its reason.

Error Handling Best Practices

Robust error handling is essential for production email sending. SMTP errors fall into several categories, and each requires a different response strategy.

Connection errors (timeouts, DNS failures, TLS handshake failures) indicate a network issue between your application and the SMTP server. These are transient and should be retried with exponential backoff. Start with a 1-second delay, double it on each retry, and cap at 60 seconds. Limit total retries to 5 attempts before failing the send and alerting your operations team.

Authentication errors (535 response codes) indicate invalid credentials. Do not retry these; they will fail every time with the same credentials. Log the error, alert your team, and check that your SMTP credentials are correctly configured in your environment variables.

Recipient errors (550, 551, 552, 553 response codes) indicate a problem with the recipient address. Hard bounces (550 "user unknown") mean the address does not exist and should be removed from your database immediately. Soft bounces (452 "mailbox full") are temporary and the message can be retried later.

Rate limiting errors (421 or 450 response codes with "too many connections" or "rate limit exceeded" messages) mean you are sending too fast. Implement exponential backoff and reduce your concurrent connection count. If you consistently hit rate limits, contact QUEENSMTP support to discuss increasing your sending rate.

Critical Rule: Never retry a message that received a permanent failure (5xx response code). Retrying permanent failures wastes resources, annoys recipients (if the address exists but rejects your email), and can damage your sender reputation. Only retry messages that received transient failures (4xx response codes) or connection errors.

SMTP in CI/CD Pipelines

CI/CD pipelines often need to send email for deployment notifications, test reports, and alerting. Configuring SMTP in your pipeline is straightforward: store your QUEENSMTP credentials as pipeline secrets (environment variables), and use a command-line email tool or your application's email sending code to send messages during the pipeline run.

For simple notifications, command-line tools like swaks (Swiss Army Knife for SMTP) can send email directly from a pipeline step without any application code. For GitHub Actions, GitLab CI, and Jenkins, install swaks and use it to send a formatted notification at the end of your deployment pipeline.

# GitHub Actions - send deployment notification
- name: Send deployment notification
  env:
    SMTP_USER: ${{ secrets.SMTP_USER }}
    SMTP_PASS: ${{ secrets.SMTP_PASS }}
  run: |
    swaks --to ops@example.com \
          --from deploy@example.com \
          --server smtp.queensmtp.com:587 \
          --auth LOGIN \
          --auth-user "$SMTP_USER" \
          --auth-password "$SMTP_PASS" \
          --tls \
          --header "Subject: Deployed ${{ github.repository }} to production" \
          --body "Commit: ${{ github.sha }} by ${{ github.actor }}"

Email Testing in Automated Tests

Automated test suites should verify that your application sends the correct emails at the correct times without actually delivering messages. There are several strategies for testing email in automated tests, depending on the level of confidence you need.

Mock the SMTP transport: In unit tests, replace your email sending function with a mock that captures the arguments passed to it. This verifies that your application constructs the correct email (recipient, subject, body, headers) without any network calls. This is the fastest and most reliable approach for unit tests.

Use a local capture server: In integration tests, run MailHog in a Docker container alongside your application. Your tests send real emails through the SMTP transport, and then query the MailHog API to verify the captured messages. This tests the complete email sending path including SMTP connection, authentication, and message formatting.

Use the QUEENSMTP sandbox API: For end-to-end tests, send email through the QUEENSMTP sandbox and use the API to retrieve and verify captured messages. This tests the complete path through your production SMTP provider while ensuring no email is delivered to real recipients.

Developer-Friendly Features

QUEENSMTP includes several features specifically designed to improve the developer experience and accelerate email integration.

Detailed Logs

Every email sent through QUEENSMTP is logged with comprehensive detail: SMTP transaction log, authentication status, DNS lookup results, delivery attempts and responses, and final status. You can search logs by message ID, recipient, sender, subject, or date range. For debugging deliverability issues, the transaction log shows the exact SMTP conversation between our server and the recipient's mail server, including response codes and error messages.

API Playground

Your API keys, the full request and response reference, and the current limits live on the API page of your dashboard. That page is generated from the running service, so it is the authoritative reference — if anything here disagrees with it, believe the dashboard.

The whole API

There are two endpoints, both authenticated with Authorization: Bearer YOUR_API_KEY against https://queensmtp.com/v1:

  • POST /v1/send — send one message. Fields: from, fromName, to, subject, html, text, replyTo, headers, isBulk.
  • GET /v1/messages/:id — delivery status for a message you sent.

One recipient per request: send to a list by making one request per address. Set isBulk: true on marketing mail so it is routed and rate-limited as bulk, and so a one-click unsubscribe header is attached.

Production SMTP Best Practices

Moving from development to production requires attention to several best practices that ensure your email integration is reliable, performant, and resilient under load. Our SMTP server setup guide covers the full configuration process in detail.

Connection Pooling

Opening a new SMTP connection for every email is expensive. Each connection requires a TCP handshake, TLS negotiation, and SMTP authentication, which adds latency and consumes server resources. Connection pooling reuses established connections for multiple messages, dramatically reducing overhead. Most SMTP libraries support connection pooling: Nodemailer has the pool: true option, Java's Session object reuses connections, and Python's smtplib supports keep-alive connections. Configure your pool to maintain 3-10 connections depending on your sending volume.

Retry Logic

Implement exponential backoff with jitter for transient SMTP errors. A simple retry with fixed delays can cause thundering herd problems when many application instances retry simultaneously after a brief outage. Exponential backoff with random jitter spreads retry attempts over time, reducing load on the SMTP server and improving recovery. Use a maximum of 3-5 retry attempts for transient errors, and never retry permanent failures.

Rate Limiting

Even with unlimited SMTP plans, implement application-side rate limiting to prevent runaway processes from sending excessive email. A bug in a notification loop can generate millions of unwanted emails in minutes if there is no rate limit in place. Use a token bucket or sliding window rate limiter to cap your application's sending rate at a sensible maximum, and alert your team if the rate limit is consistently being hit, which indicates either a traffic spike or a bug.

Queue-Based Architecture

For high-volume applications, decouple email sending from your request handling path using a message queue. When your application needs to send an email, it enqueues a message to a queue (Redis, RabbitMQ, SQS, etc.) and returns immediately. A background worker process reads from the queue and sends the email via SMTP. This architecture prevents email sending latency from affecting your application's response times, provides natural retry handling through the queue's redelivery mechanism, and allows you to scale email sending workers independently of your web servers.

Monitoring and Alerting

Instrument your email sending code with metrics for send count, error count, error rate, and send latency. Track these metrics in your application monitoring system (Datadog, New Relic, Prometheus, etc.) and set alerts for anomalies. A sudden increase in error rate may indicate an SMTP configuration issue, a credential expiration, or a deliverability problem. A sudden increase in send volume may indicate a bug. Monitoring lets you detect and respond to these issues before they affect your users.

Production Checklist: Before going live, verify these items: domain authentication (SPF, DKIM, DMARC) is configured and passing, environment variables point to production SMTP credentials, connection pooling is enabled, retry logic handles transient errors with exponential backoff, rate limiting prevents runaway sending, bounces and complaints are reviewed in the dashboard to maintain list hygiene (webhooks for this are in development), and monitoring alerts are set up for error rate and volume anomalies.

SMTP for Developers FAQ

A good SMTP server for developers prioritizes ease of integration, debugging tools, and a smooth development-to-production pipeline. Key features include: standard SMTP credentials that work with any programming language (no proprietary SDK lock-in), a RESTful API with comprehensive documentation and code examples, code examples for Node.js, Python, PHP and cURL, detailed sending logs with full SMTP transaction data for debugging, per-message delivery status via the API (event webhooks in development), quick setup (under 5 minutes from signup to first email sent), and clear, predictable pricing without surprise charges. QUEENSMTP.COM is built with developers in mind, providing all of these features plus a generous free tier of 1,000 emails per month for development and testing.

Integrating SMTP into your application is straightforward regardless of your technology stack. The basic pattern is the same across all languages: install an SMTP/email library, configure it with your QUEENSMTP.COM credentials (host, port 587, TLS, username, password), compose a message with headers and body, and send it. In Node.js, use Nodemailer — install with npm install nodemailer, create a transport with your SMTP settings, and call transporter.sendMail(). In Python, use the built-in smtplib module or the popular email library. In PHP, use PHPMailer or Symfony Mailer. In Ruby, use the mail gem or ActionMailer. In Java, use JavaMail or Spring Mail. In Go, use net/smtp or gomail. In C#, use System.Net.Mail.SmtpClient or MailKit. QUEENSMTP.COM also provides a REST API if you prefer HTTP-based integration — make a POST request with your API key and email data in JSON format. Both SMTP and API methods are fully documented with copy-paste code examples in our developer documentation.

The choice depends on your use case and existing infrastructure. Use SMTP when: your application or framework has built-in SMTP support (WordPress, Laravel, Django, Rails), you are integrating with an existing mail server or infrastructure, you need maximum compatibility with any system, or you want no vendor-specific dependencies. Use REST API when: you are building a new application from scratch, you need batch sending (up to 1,000 recipients per request), you want synchronous response with immediate message ID, you need template management and variable substitution through the API, or you prefer modern HTTP-based integration patterns. In practice, many developers use both: SMTP for the main application email integration (leveraging framework-built-in SMTP support) and REST API for programmatic sending with a message id and delivery status per send (webhooks in development). QUEENSMTP.COM provides identical deliverability and features through both methods.

There are several approaches to testing SMTP in development. QUEENSMTP.COM sandbox mode lets you send emails through the real SMTP infrastructure but suppresses actual delivery — emails appear in your dashboard with full delivery simulation data but never reach real recipients. This tests your complete integration including authentication and formatting. Local SMTP capture tools like Mailtrap, MailHog, or Mailpit run on your development machine and catch all outgoing SMTP emails in a web interface for inspection. These are great for rapid development but do not test authentication or deliverability. Environment-based configuration is a best practice: use environment variables for SMTP settings so you can switch between local capture (development), QUEENSMTP.COM sandbox (staging), and QUEENSMTP.COM production (live) without code changes. For automated testing (unit and integration tests), mock the SMTP transport or use a recording library that captures sent messages for assertion without network calls.

A third-party SMTP server is an external email delivery service that your application uses instead of sending email directly from your own server. You should use one because modern email delivery is complex — major email providers (Gmail, Outlook, Yahoo) implement sophisticated filtering that blocks email from unknown or untrusted sources. Building and maintaining email delivery infrastructure requires expertise in IP reputation management, authentication protocols, ISP relationships, deliverability monitoring, and abuse prevention. A third-party SMTP service like QUEENSMTP.COM handles all of this, letting you focus on building your application. Additional benefits include: pre-warmed IP addresses with established reputation, automatic authentication handling, delivery analytics and troubleshooting tools, compliance with email standards and regulations, scalability from hundreds to millions of emails, and expert support when delivery issues arise. The cost (just $5/year plus $0.10 per 1,000 emails for most applications) is a tiny fraction of what it would cost to build and maintain equivalent infrastructure yourself.

Robust email error handling involves several layers. At the SMTP connection level, catch connection timeout errors (server unreachable), authentication failures (wrong credentials), and TLS errors (certificate issues). Implement exponential backoff retry logic: wait 1 second after first failure, 2 seconds after second, 4 seconds after third, up to a maximum of 5 retries. At the message level, validate email addresses before sending (basic format validation), handle recipient rejection errors (550 user not found), and catch message size limit errors. For asynchronous delivery tracking, store the message ID returned by the QUEENSMTP.COM API and poll GET /v1/messages/:id. Webhooks that POST bounce, complaint and delivery events to your endpoint are in development and will carry the same message ID. Implement a dead letter queue for emails that fail after all retries — log them for manual review rather than silently dropping them. For critical transactional emails like password resets, consider implementing a fallback SMTP provider as a secondary sending path.

Serverless functions have specific constraints for email sending: short execution timeouts, no persistent connections, and cold start latency. For SMTP sending from serverless, keep in mind that each invocation creates a new SMTP connection (connection pooling is not possible across invocations), so use the QUEENSMTP.COM REST API instead of SMTP for better performance — HTTP requests are faster than establishing SMTP sessions for one-off sends. In AWS Lambda (Node.js), install the QUEENSMTP.COM SDK or use axios/fetch to call the REST API endpoint with your API key. In Vercel serverless functions, use the same HTTP approach. In Cloudflare Workers, use the Fetch API to call QUEENSMTP.COM REST endpoint (Workers cannot make raw TCP connections, so SMTP is not possible). For all serverless platforms, store your QUEENSMTP.COM API key in environment variables or secrets manager, not in code. Set appropriate timeouts (10 seconds is usually sufficient for a single email send). For bulk sending from serverless, trigger a queue (SQS, Pub/Sub) and process sends in batches rather than invoking one function per email.

Production SMTP integration should follow these best practices. Configuration: store all SMTP credentials in environment variables, never in code or config files committed to version control. Use different SMTP credentials for development, staging, and production environments. Connection management: reuse SMTP connections when sending multiple emails (connection pooling reduces overhead), set appropriate connection timeouts (30 seconds for connection, 60 seconds for sending), and implement graceful connection cleanup. Error handling: implement retry logic with exponential backoff, handle both transient (try again) and permanent (do not retry) SMTP errors, log all sending attempts with message IDs for debugging. Monitoring: track sending rate, error rate, and latency metrics, set up alerts for unusual error patterns, and monitor bounces and complaints in the QUEENSMTP.COM dashboard log (webhook events once webhooks ship). Security: use TLS for all SMTP connections, rotate SMTP credentials periodically, restrict sending permissions to only necessary applications. Rate limiting: respect your plan sending limits, implement application-level rate limiting to prevent accidental bursts that could trigger provider throttling.

QUEENSMTP.COM provides official SDKs for Node.js, Python, PHP, Ruby, Java, Go, and C#. All SDKs wrap our REST API with idiomatic interfaces for each language. You can also use standard SMTP libraries (Nodemailer, smtplib, PHPMailer, etc.) with QUEENSMTP.COM SMTP credentials — no proprietary SDK required. Our developer documentation includes copy-paste code examples for every language.

Webhooks are in development. When they ship you will register an HTTPS endpoint from the dashboard or the API, and QUEENSMTP.COM will POST signed JSON events for delivered, deferred, bounced, complained, opened, clicked, unsubscribed and rejected messages, each with an event ID to deduplicate on and the message ID returned by /v1/send. Until then, read per-message status from GET /v1/messages/:id or the dashboard message log.

Yes, QUEENSMTP.COM works perfectly with containerized applications. Store SMTP credentials as environment variables or Docker secrets, configure your application SMTP library with these variables, and your containers can send email through QUEENSMTP.COM from any environment. No local mail server is needed inside the container — just point to QUEENSMTP.COM SMTP host and port 587.

For SMTP-based sending, manage templates in your application code using template engines (Handlebars, EJS, Jinja2, Blade). Render the template with dynamic data before sending via SMTP. QUEENSMTP.COM REST API also supports server-side templates — create templates in the dashboard with {{variable}} placeholders and pass variable values per recipient in your API call for centralized template management.

Rate limits vary by plan: Free tier supports 10 emails per minute, Starter supports 100 per minute, Professional supports 1,000 per minute, and Enterprise supports custom rates up to 10,000+ per minute. These limits protect deliverability by preventing sudden bursts that could trigger ISP throttling. If you need higher rates, contact our team for custom configuration.

Enable verbose SMTP logging in your library (Nodemailer debug:true, Python set_debuglevel(1)). Check that your firewall allows outbound connections on port 587. Use openssl s_client -starttls smtp -connect smtp.queensmtp.com:587 to test TLS connectivity. Verify credentials by logging into the QUEENSMTP.COM dashboard. Our sandbox mode lets you test the full SMTP flow without delivering to real recipients.

Yes, QUEENSMTP.COM is commonly used in CI/CD pipelines for sending deployment notifications, test reports, and alert emails. Configure SMTP credentials as pipeline secrets in GitHub Actions, GitLab CI, Jenkins, or CircleCI. Use our REST API with curl for simple notifications, or your application SMTP library for more complex emails. Sandbox mode is ideal for automated test suites.

Hard bounces are suppressed automatically and listed on the dashboard Bounces page, and each message's status is available from GET /v1/messages/:id. Bounce webhooks are in development; when they ship, each bounce event will include the recipient address, bounce type (hard or soft), bounce code, and diagnostic message. Process hard bounces by immediately removing the address from your database. For soft bounces, implement retry logic with a maximum attempt count before permanent suppression.

Start Building with QUEENSMTP

Free sandbox environment, code examples for every language, and production-ready SMTP infrastructure. Sign up and send your first email in under five minutes. No credit card required for the free developer tier.

Send email over SMTP in your language

Complete, runnable examples with STARTTLS on 587, credentials from the environment, HTML + text bodies and the errors each library reports — plus the one-line host swap for Gmail, SES and Office 365.

PHP (PHPMailer) Laravel WordPress Python Django Flask Node.js (Nodemailer) Next.js Java C# / .NET Go Ruby on Rails Postfix relayhost curl / Bash

Before you write code: test the server and your credentials, and look up your provider's exact values on the SMTP settings hub.