INTEGRITY Cloudflare Docs

Send email over SMTP

Send transactional emails over Cloudflare Email Service authenticated SMTP (smtp.mx.cloudflare.net:465) from any SMTP-capable language or client.

Prerequisites

Send an email

cat > mail.txt <<EOF
From: [email protected]
To: [email protected]
Subject: Welcome to our service!

Thanks for signing up.
EOF

curl --ssl-reqd \
  --url "smtps://smtp.mx.cloudflare.net:465" \
  --user "api_token:$CF_API_TOKEN" \
  --mail-from "[email protected]" \
  --mail-rcpt "[email protected]" \
  --upload-file mail.txt

The sender domain must be onboarded for Email Sending on the account that owns the API token.

Install Nodemailer with npm install nodemailer.

Send an email

import nodemailer from "nodemailer";

const transporter = nodemailer.createTransport({
	host: "smtp.mx.cloudflare.net",
	port: 465,
	secure: true, // implicit TLS
	auth: {
		user: "api_token",
		pass: process.env.CF_API_TOKEN,
	},
});

const info = await transporter.sendMail({
	from: '"Acme" <[email protected]>',
	to: "[email protected]",
	subject: "Welcome to Acme",
	text: "Thanks for signing up.",
	html: "<h1>Welcome to Acme</h1><p>Thanks for signing up.</p>",
});

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

Send with an attachment

const info = await transporter.sendMail({
	from: '"Acme Billing" <[email protected]>',
	to: "[email protected]",
	subject: "Your invoice",
	text: "Please find your invoice attached.",
	attachments: [
		{
			filename: "invoice-2026-04.pdf",
			path: "./invoices/invoice-2026-04.pdf",
			contentType: "application/pdf",
		},
	],
});

Total message size (including base64-encoded attachments) must not exceed 5 MiB. See Limits.

Error handling

Nodemailer rejects the promise with an Error whose .responseCode reflects the SMTP reply code. See SMTP response codes and Troubleshooting.

try {
	await transporter.sendMail({
		/* ... */
	});
} catch (err) {
	console.error(err.responseCode, err.message);
}

Uses the standard-library smtplib (Python 3.8 or later).

Send an email

import os
import smtplib
from email.message import EmailMessage

msg = EmailMessage()
msg["From"] = "Acme <[email protected]>"
msg["To"] = "[email protected]"
msg["Subject"] = "Welcome to Acme"
msg.set_content("Thanks for signing up.")
msg.add_alternative(
    "<h1>Welcome to Acme</h1><p>Thanks for signing up.</p>",
    subtype="html",
)

with smtplib.SMTP_SSL("smtp.mx.cloudflare.net", 465) as s:
    s.login("api_token", os.environ["CF_API_TOKEN"])
    s.send_message(msg)

smtplib.SMTP_SSL opens an implicit-TLS connection on port 465, which is what Cloudflare's SMTP endpoint requires. Do not use smtplib.SMTP with starttls(); STARTTLS is not supported.

Send to multiple recipients

msg["To"] = ", ".join([
    "[email protected]",
    "[email protected]",
    "[email protected]",
])

A single SMTP session can deliver to up to 50 RCPT TO addresses. See Limits.

Send with an attachment

from pathlib import Path

pdf = Path("invoice-2026-04.pdf").read_bytes()
msg.add_attachment(
    pdf,
    maintype="application",
    subtype="pdf",
    filename="invoice-2026-04.pdf",
)

Error handling

smtplib raises subclasses of smtplib.SMTPException with the SMTP reply code attached. See SMTP response codes and Troubleshooting.

try:
    with smtplib.SMTP_SSL("smtp.mx.cloudflare.net", 465) as s:
        s.login("api_token", os.environ["CF_API_TOKEN"])
        s.send_message(msg)
except smtplib.SMTPAuthenticationError as e:
    print(f"Auth failed: {e.smtp_code} {e.smtp_error!r}")
except smtplib.SMTPResponseException as e:
    print(f"SMTP error: {e.smtp_code} {e.smtp_error!r}")

Send an email

<?php
use PHPMailer\PHPMailer\PHPMailer;

require 'vendor/autoload.php';

$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host       = 'smtp.mx.cloudflare.net';
$mail->Port       = 465;
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
$mail->SMTPAuth   = true;
$mail->Username   = 'api_token';
$mail->Password   = getenv('CF_API_TOKEN');

$mail->setFrom('[email protected]', 'Acme');
$mail->addAddress('[email protected]');
$mail->Subject = 'Welcome to our service!';
$mail->Body    = 'Thanks for signing up.';
$mail->send();

Next steps