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 = 465SMTP_USER = "[email protected]"SMTP_PASSWORD = "<mailbox-password>"SMTP_FROM = "[email protected]"SMTP_FROM_NAME = "Example"
465: implicit TLS587: STARTTLSPython: 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 smtplibimport sslfrom getpass import getpassfrom email.message import EmailMessagefrom 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"] = recipientmessage["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.