Skip to main content

Send email with SMTP

Send email from any app, framework or plugin that supports SMTP, using your SendMero API key as the password.

If your app already sends mail over SMTP, you can switch to SendMero by changing its mail settings. There is no new SDK to install. Prefer JSON over HTTP? Use the REST API instead; see SMTP or the REST API? below.

Quickstart​

  1. Verify your sending domain. Add the domain you send from and publish its DNS records. Your messages' From address must be on this domain. Add your domain →
  2. Create an API key. The same key you use for the REST API works as your SMTP password. Create an API key →
  3. Enter these settings in your app:
SettingValue
Hostsmtp.sendmero.com
Port with STARTTLS587 (or 2587)
Port with implicit TLS (SSL/TLS)465 (or 2465)
Usernamesendmero
PasswordYour SendMero API key, including its live_ prefix

That is all the setup there is. The username is always sendmero, and there is no separate SMTP password to create.

Send your first email​

Pick your language or framework, replace the from address with one on your verified domain, set SENDMERO_API_KEY to your key, and run it.

SMTP
SMTP_USERNAME='sendmero'
SMTP_PASSWORD="$SENDMERO_API_KEY" # your API key

curl --ssl-reqd --url 'smtp://smtp.sendmero.com:587' \
--user "$SMTP_USERNAME:$SMTP_PASSWORD" \
--mail-from 'hello@example.com' \
--mail-rcpt 'recipient@example.net' \
--upload-file - <<'EOF'
From: Example Store <hello@example.com>
To: recipient@example.net
Subject: Hello from SendMero
X-SendMero-Metadata: {"order_id":"88231"}

Sent over SMTP.
EOF
# Implicit TLS: use smtps://smtp.sendmero.com:465 instead of smtp://...:587 --ssl-reqd.

When SendMero accepts the message, your library receives this reply:

250 2.0.0 Ok: queued as msg_9f2c6a1e4b7d4c0e8a5b3d2f1e0c9b8a

msg_… is the message ID. Keep it: you can paste it into Activity in the dashboard to find the email. Accepted means SendMero has taken the message for sending; it is not a delivery confirmation.

Choose a port and encryption​

SendMero only accepts SMTP on an encrypted connection (TLS 1.2 or later). Pick the port that matches what your library supports:

EncryptionPortNotes
STARTTLS (the connection starts plain, then upgrades)587The usual choice. Libraries call this "STARTTLS" or "TLS".
SSL/TLS (encrypted from the first byte)465Use it if your library only offers "SSL".
STARTTLS2587Use if your host blocks port 587.
SSL/TLS2465Use if your host blocks port 465.

Build your message​

Compose the message with your mail library as you normally would. This is how SendMero treats each part:

To do thisWhat to do
Set the senderUse an address on your verified domain as From. A display name works: Example Store <hello@example.com>.
Send HTML and plain textSend both parts (a multipart/alternative message) as your library does by default.
Cc and BccAdd them as usual. Bcc recipients are not shown to anyone else.
Set Reply-ToAdd a Reply-To header or use your library's reply-to option.
Attach filesAttach them as usual. The whole message, attachments included, must stay under about 90 KB.
Add an unsubscribe linkAdd a List-Unsubscribe header, and List-Unsubscribe-Post: List-Unsubscribe=One-Click for one-click unsubscribe.
Attach your own data (metadata)Add an X-SendMero-Metadata header with a JSON object, for example {"order_id":"88231"}. It is kept with the message and appears in Activity and in webhook events. It is never sent to the recipient. See Attach metadata.
Add your own headersHeaders that start with X- are kept, up to 10 custom headers in total (List-* headers count too). X-SendMero-* headers are reserved for SendMero. Message-ID, Date and similar headers are set by SendMero.
Send to several peopleUp to 100 recipients per message. For more, send more than one message.

A message needs at least one To recipient. Inline images (cid: references) arrive as ordinary attachments.

Attach metadata​

Metadata is your own data about a message, such as an order or customer ID. Over SMTP you pass it in one header, as a JSON object of text values:

X-SendMero-Metadata: {"order_id":"88231","customer_id":"c-42"}
  • It is the same metadata the REST API takes: at most 10 keys, key names of letters, digits and underscores (up to 40 characters), text values up to 256 characters, and 2,048 bytes in total.
  • It appears with the message in Activity and in the metadata field of webhook events, so you can match an email to your own records.
  • It is not sent to the recipient. SendMero removes the header before the email goes out.
  • Use text values. A number such as {"qty":3} is refused; write {"qty":"3"}.
  • If the header isn't valid JSON, or breaks a rule, the message is refused with a 554 reply that says what to fix. Nothing is sent.

Most mail libraries add a custom header with one line. The examples above show it for each language. Non-ASCII values (such as Zürich) are fine; your library encodes the header and SendMero decodes it.

After you send​

  • Find the message. Open Activity and search by the msg_… ID or the recipient to see whether it was delivered, bounced or deferred.
  • Get notified. Webhooks report delivery events for messages sent over SMTP the same way as for the REST API.
  • If it didn't send, the reply tells you why. See below.

Replies you may see​

Your mail library treats a 4xx reply as "try again later" and a 5xx reply as "give up". Most libraries retry 4xx replies by themselves.

ReplyWhat it meansWhat to do
250Accepted, queued as msg_….Nothing. Keep the message ID.
451A temporary problem, or your workspace reached a sending limit.Retry later.
452 4.5.3More than 100 recipients.Split the message.
421Too many connections or too many wrong keys from your IP address.Close idle connections or fix your key, then wait and retry.
535The API key is wrong, expired or revoked, or the username is not sendmero.Check the username and use a current key.
538You tried to log in before starting encryption.Turn on STARTTLS or SSL/TLS in your app.
550 5.7.1The From domain isn't set up, verified or ready, or sending is paused for the workspace. The reply says which.Fix the domain in Sending Domains.
552The message is too large.Make it smaller; the limit is about 90 KB.
554 5.6.0The message was refused, for example it has no To recipient, an invalid field, or invalid X-SendMero-Metadata. The reply says why.Correct the message.
554 5.7.0You are out of email credits.Top up credits, then send again.

Limits​

LimitValue
Message size, attachments includedAbout 90 KB
Recipients per message100
Open connections from one IP address20
Idle connectionClosed after 60 seconds
Wrong API keysAfter 10 within 10 minutes, connections from that IP address are refused for 15 minutes

Your workspace's daily and monthly sending limits and your email credits apply exactly as they do for the REST API. See Rate Limits & Retries.

Troubleshooting​

"Test connection" passes, but my email doesn't send. SendMero checks your API key when you send a message, not when you connect. Most "test connection" buttons only connect, so they pass even with a wrong key. Send a real test email to confirm your settings. A wrong key shows up as a 535 reply.

The connection times out or is refused. Your network or host may block the port. Try 2587 (STARTTLS) or 2465 (SSL/TLS) instead.

I get a certificate or TLS error. Check that the host is exactly smtp.sendmero.com and that the encryption setting matches the port: STARTTLS for 587 and 2587, SSL/TLS for 465 and 2465. Your library must support TLS 1.2 or later.

Every message gets 535. The password must be your whole API key, starting with live_, with no spaces or quotes around it. Confirm the key is still active under Credentials in the dashboard.

I get 550. The From address must be on a domain that shows as verified under Sending Domains. A verified example.com does not cover mail.example.com; verify the exact domain you send from.

My message is refused with a metadata error. X-SendMero-Metadata must be a JSON object of text values within the limits in Attach metadata. The 554 reply names the problem, for example metadata: at most 10 keys are allowed.

I need test mode. Test mode is a REST API feature and isn't available over SMTP. To try SMTP, send a message to an address you own.

SMTP or the REST API?​

Both use the same API key, the same verified domains, and the same sending limits and credits, so you can use either, or both.

SMTPREST API
Best forExisting apps, frameworks and plugins that already send over SMTPNew code that can make HTTP requests
RequestA normal email messageA JSON body
metadata on the messageYes, in the X-SendMero-Metadata headerYes, in the body
Test modeNoYes
Custom headersList-* and X- headers (not X-SendMero-*)Any header that is not reserved
ResultA 250 reply with the message IDJSON with the message ID
ErrorsSMTP reply codes (above)error.code and an HTTP status (Error Codes)