Skip to content
English

Sending via SMTP

Before you connect

Send email from your application via SMTP using a mailbox username and password. API keys and account tokens cannot be used for SMTP.

Create an active mailbox on a connected domain and complete its DNS verification. The username is the full address, such as [email protected]. Use the mailbox password, not the mail account password. Replace the example addresses with your own; the password is entered at runtime without being displayed.

Server, ports and encryption

Use mail.adapt-mail.com for any connected domain. Port 465 starts TLS immediately; port 587 uses STARTTLS before authentication. Choose one option. Keep certificate verification enabled.

In these examples, the From address and SMTP envelope sender match the mailbox username. You can change the sender display name. Port 25 is for communication between mail servers; use 465 or 587 for your application.

SMTP_HOST = "mail.adapt-mail.com"
SMTP_PORT = 465
SMTP_USER = "[email protected]"
SMTP_PASSWORD = "<mailbox-password>"
SMTP_FROM = "[email protected]"
SMTP_FROM_NAME = "Example"
465: implicit TLS
587: STARTTLS

Python: sending on port 465

This example uses only the Python 3 standard library. Save it as send_mail.py and run python3 send_mail.py. For automated sending, retrieve the password from your application's secure configuration; do not store it in Git or logs.

import smtplib
import ssl
from getpass import getpass
from email.message import EmailMessage
from email.utils import formataddr, make_msgid, formatdate
username = "[email protected]"
password = getpass("SMTP password: ")
recipient = "[email protected]"
message = EmailMessage()
message["From"] = formataddr(("Example", username))
message["To"] = recipient
message["Subject"] = "SMTP test"
message["Date"] = formatdate(localtime=False, usegmt=True)
message["Message-ID"] = make_msgid(domain=username.split("@")[1])
message.set_content("Hello! This message was sent through Adapt Mail SMTP.")
with smtplib.SMTP_SSL(
"mail.adapt-mail.com", 465, timeout=30,
context=ssl.create_default_context(),
) as smtp:
smtp.login(username, password)
refused = smtp.send_message(
message, from_addr=username, to_addrs=[recipient],
)
print("Rejected recipients:", refused)

Python: connecting on port 587

For STARTTLS, keep the message preparation from the previous example and replace the with smtplib.SMTP_SSL block with the following. With smtplib.SMTP, the password is sent only after STARTTLS succeeds.

with smtplib.SMTP("mail.adapt-mail.com", 587, timeout=30) as smtp:
smtp.ehlo()
smtp.starttls(context=ssl.create_default_context())
smtp.ehlo()
smtp.login(username, password)
refused = smtp.send_message(
message, from_addr=username, to_addrs=[recipient],
)
print("Rejected recipients:", refused)

HTML and attachments

Add the HTML alternative after set_content and the attachment before sending. Keep the plain text version for clients without HTML support. Use trusted HTML or escape any interpolated data.

message.add_alternative(
"<p>Hello! This message was sent through <strong>Adapt Mail</strong>.</p>",
subtype="html",
)
with open("document.pdf", "rb") as attachment:
message.add_attachment(
attachment.read(), maintype="application", subtype="pdf",
filename="document.pdf",
)

Results, limits and sent messages

A successful send_message means the SMTP server accepted the message, not that it reached the recipient's inbox. The refused dictionary lists rejected recipients; if all recipients are rejected, Python raises SMTPRecipientsRefused.

SMTP and API share the same per-mailbox limits: up to 30 messages in a rolling 60-second window, 50 recipients per message, and 1000 recipients in a rolling 24-hour window, or 5000 with the higher limit enabled. All To, Cc and Bcc recipients count.

Direct SMTP sending does not itself save a copy in Sent. Mail clients do this through IMAP; sending through the Adapt Mail API saves a copy separately.

SMTP errors

535
Authentication failed: check the full address, mailbox password and mailbox availability.
451
Temporary failure, including sending limits being exceeded. Retry later with a delay.
550 / 5xx
Permanent failure: check the addresses, sender permissions and response text. More than 50 recipients are rejected after DATA. Fix the cause before retrying.
TLS / timeout
Check the hostname mail.adapt-mail.com, port, TLS mode and outbound access from your application server. Use SMTP_SSL on 465, or SMTP with STARTTLS on 587.

Read the full SMTP server response. Retry temporary failures with a delay. If the connection drops after transmitting the message and the outcome is unknown, do not resend blindly: SMTP has no Idempotency-Key, and a retry may create a duplicate.