SMTP

SMTP Integration

Send emails using standard SMTP protocol. Get your credentials from the SMTP Settings page in your dashboard.

Before you start

SMTP credentials can only be generated once you are able to send. Pick the path that matches how you send:

Your own domain

Verified domain

Add your sending domain and publish the DNS records. Once it shows as verified, you can send from any address on it.

Open Domains →

Shared domain

Registered sender

No domain of your own? Register the sender address you want to use. Only registered senders can send on a shared domain.

Open Senders →
i

Then get your credentials: open Dashboard → SMTP Settings to generate your username and password.

Server Settings

Host

smtp.emailsbit.com

SMTP server hostname

Ports

505 · 588

Available connection ports (588 recommended with STARTTLS)

Security

STARTTLS

Recommended security protocol

Port 505

None

Unencrypted connection (not recommended for production)

Port 588

STARTTLSrecommended

Opportunistic TLS encryption — starts as plain text, upgrades to TLS

!

Security best practices: Never hardcode credentials in your source code. Use environment variables or a secure secrets manager.

Transactional

Order confirmations, password resets, receipts. Connect on port 588 with STARTTLS and send. No extra headers needed.

const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
  host: 'smtp.emailsbit.com',
  port: 588,
  secure: false, // STARTTLS: starts as plain text, upgrades to TLS
  requireTLS: true,
  auth: {
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS,
  },
});

async function main() {
  await transporter.sendMail({
    from: '"Support" <support@yourdomain.com>',
    to: 'user@example.com',
    subject: 'Your Order Confirmation',
    html: '<h2>Thank you for your purchase!</h2>',
  });
}

main().catch(console.error);

Marketing

Newsletters and campaigns. Add the list headers below so mail clients show an Unsubscribe button and complaints are tracked per campaign. They are parsed and applied automatically, with no extra API call.

const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
  host: 'smtp.emailsbit.com',
  port: 588,
  secure: false, // STARTTLS: starts as plain text, upgrades to TLS
  requireTLS: true,
  auth: {
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS,
  },
});

async function main() {
  await transporter.sendMail({
    from: '"Support" <support@yourdomain.com>',
    to: 'user@example.com',
    subject: 'Our October newsletter',
    html: '<h2>What is new this month</h2>',
    headers: {
      'List-Id': 'My List <mylist.yourdomain.com>',
      'X-Report-Abuse': 'https://yourdomain.com/report-abuse',
      'Feedback-ID': 'campaign123:subscriber456:list789:youraccount',
      'List-Unsubscribe': '<mailto:unsubscribe@yourdomain.com?subject=unsubscribe>,<https://yourdomain.com/unsubscribe?u=123>',
      'List-Unsubscribe-Post': 'List-Unsubscribe=One-Click',
    },
  });
}

main().catch(console.error);

Reserved headers

These five are accepted as they are, with no X- prefix.

List-Id

Identifies the mailing list or sending stream a message belongs to. Mailbox providers and mail clients use it to group and filter messages from the same list.

Display name followed by a list identifier in angle brackets.

My List <mylist.yourdomain.com>
X-Report-Abuse

A URL where recipients can report the message as abuse or spam.

A full URL.

https://yourdomain.com/report-abuse
Feedback-ID

Tags the message with your own identifiers so feedback-loop reports (such as complaint rates in Gmail Postmaster Tools) can be broken down by campaign, subscriber or list.

Colon-separated fields: campaign : subscriber : list : your account.

campaign123:subscriber456:list789:youraccount
List-Unsubscribe

Tells mail clients how to unsubscribe the recipient, which enables the native "Unsubscribe" button next to the sender name.

One or more URIs in angle brackets, separated by commas. Accepts mailto: and https: URIs.

<mailto:unsubscribe@yourdomain.com?subject=unsubscribe>,<https://yourdomain.com/unsubscribe?u=123>
List-Unsubscribe-Post

Enables one-click unsubscribe (RFC 8058). The mail client sends a POST request to the https URI in List-Unsubscribe, with no confirmation page in between.

The fixed value below. Requires an https URI in List-Unsubscribe.

List-Unsubscribe=One-Click

One-click unsubscribe

Set List-Unsubscribe and List-Unsubscribe-Post together and the recipient can unsubscribe straight from the mail client.

  1. 1

    Add both headers

    Set List-Unsubscribe with an https URL, and List-Unsubscribe-Post with the fixed value.

  2. 2

    Recipient clicks Unsubscribe

    The mail client shows its own button. The recipient never visits your site.

  3. 3

    Client sends a POST

    The request goes to your https URL with the body below, with no cookies and no user interaction.

  4. 4

    Your endpoint unsubscribes

    Remove the recipient and answer with a 2xx status. Do not redirect or ask for a login.

Request your endpoint receives

POST /unsubscribe?u=123 HTTP/1.1
Host: yourdomain.com
Content-Type: application/x-www-form-urlencoded

List-Unsubscribe=One-Click

Custom headers

Attach your own metadata to any message, transactional or marketing, with a header that starts with X-.

const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
  host: 'smtp.emailsbit.com',
  port: 588,
  secure: false, // STARTTLS: starts as plain text, upgrades to TLS
  requireTLS: true,
  auth: {
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS,
  },
});

async function main() {
  await transporter.sendMail({
    from: '"Support" <support@yourdomain.com>',
    to: 'user@example.com',
    subject: 'Your Order Confirmation',
    html: '<h2>Thank you for your purchase!</h2>',
    headers: {
      'X-MyCustomHeader': 'testcustom0',
      'X-CUSTOM-X': 'testcustom1',
    },
  });
}

main().catch(console.error);
!

Naming restriction: any header outside the reserved list must be prefixed with X-, or the message is rejected with HEADER_NOT_ALLOWED.

Valid

"X-MyCustomHeader": "testcustom0"
"X-CUSTOM-X": "testcustom1"

Invalid

"MyCustomHeader": "testcustom0"

→ HEADER_NOT_ALLOWED