Skip to content
Koltrix

SMTP or API for sending email? How to choose

SMTP and an HTTP API both send the same message. Here is what each gives you in errors, retries, metadata and tooling, and a simple way to pick one.

Koltrix Team5 min read
Yellow and green patch cables neatly connected to a panel
Photo by Albert Stoynov on Unsplash
On this page(10 sections)
  1. What each one actually is
  2. What "accepted" means in each
  3. Retries and duplicates
  4. Metadata, templates and tracking
  5. Speed and connection handling
  6. Security
  7. When SMTP is the right choice
  8. When an API is the right choice
  9. A simple way to decide
  10. Key takeaways

Most email providers offer two ways in: an SMTP relay you point your mail library at, and an HTTP API you call with a key. Both end with the same message leaving the same servers. What differs is everything around the send: how you learn it failed, how you retry safely, and how much you can attach to each message.

This is a practical guide to choosing. It does not name a winner for every case, because there isn't one.

What each one actually is

SMTP is the protocol mail servers have used for decades. Your application opens a connection, authenticates, and hands over a finished message: headers, body, attachments, all as one MIME blob. Nearly every language, framework and off-the-shelf tool can do this out of the box.

An HTTP API takes a structured request, usually JSON: a sender, recipients, a subject, the content, maybe a template and some metadata. The provider builds the MIME message for you. You get back a JSON response with an id you can use later.

Koltrix offers both: a transactional API (POST https://api.koltrix.com/api/v2/emails with an API key) and an SMTP relay. The same trade-offs apply to any provider, so the rest of this post is general. Check docs.koltrix.com for the exact settings.

What "accepted" means in each

With SMTP, a 250 OK after your message means the relay accepted responsibility for it. It does not mean the recipient got it. Delivery happens afterwards, and failures arrive later as bounces. With an API, a 2xx response means the same thing: accepted for sending, not delivered. In both cases you need webhooks or bounce handling to learn what really happened.

The difference is the shape of the error when the send is refused:

SMTP HTTP API
Bad recipient address A numeric reply code and a free-text line A structured error body naming the field
Rate limited A temporary failure code (4xx) HTTP 429 and usually a retry hint
Bad credentials Authentication failure on connect HTTP 401
Message too large A 5xx rejection after the data is sent Often rejected before the upload finishes

Structured errors are easier to log, alert on and test. SMTP codes are standardised but terse, and libraries differ in how they surface them.

Retries and duplicates

Networks fail. The question is what happens when your send times out and you do not know whether the provider got it.

  • SMTP has no built-in way to say "this is the same message as before". A retry after a timeout can produce a duplicate. Some libraries and relays deduplicate on the Message-ID header, but that depends on the provider.
  • An API can support an idempotency key: you send the same key with the retry, and the provider treats it as one send. This is the single biggest practical advantage of an API for anything that matters, such as password resets or receipts.

If your application already queues sends and retries them, make sure the retry logic knows which of the two it is talking to. See also handling rate limits and 429s.

Metadata, templates and tracking

An API request can carry fields that have no place in an SMTP message: a customer id, a campaign name, tags for filtering, a template id with variables. Those show up again in webhooks and logs, which makes it much easier to answer "what happened to the receipt we sent to this user?".

With SMTP you can still add custom headers, and some relays read them, but you are working against the protocol rather than with it. Templates, scheduling and per-message settings are usually API-only or need provider-specific headers.

Speed and connection handling

SMTP is chatty: connect, greet, secure the connection with TLS, authenticate, then send. For one message that is several round trips. Sending in volume means keeping connections open and reusing them, which many libraries do poorly by default.

An HTTP API is one request per send, or one request per batch where the provider supports it. HTTP keep-alive and connection pools are well understood in every language. For short-lived processes such as serverless functions, an API call is usually simpler and faster than setting up an SMTP session each time.

Security

Both can be done safely, and both can be done badly.

  • Use TLS for SMTP: connect on the submission port and upgrade with STARTTLS, or use implicit TLS where the provider supports it. Do not send credentials over a plain connection.
  • Treat API keys like passwords. Use one key per service so you can revoke one without breaking the others, and keep them out of source control.
  • Prefer the narrowest credential available. If your provider lets you scope a key to sending only, do that.

When SMTP is the right choice

  • You are connecting something that only speaks SMTP: a CMS, a printer, a monitoring tool, an older application, a plugin.
  • You want to switch providers by changing a hostname and credentials, with no code change.
  • Your sends are low volume and failures are rare enough that a bounce email to a human is fine.

When an API is the right choice

  • You are writing new application code and want structured errors and idempotent retries.
  • You need metadata, templates, scheduling or batch sends.
  • You run in serverless or short-lived processes.
  • You want a clean path from "message accepted" to "message delivered or bounced" in your own database.

A simple way to decide

Ask three questions:

  1. Can the sender only speak SMTP? Then use SMTP and move on.
  2. Would a duplicate or a lost send cost you something real? Then use the API with idempotency keys.
  3. Do you need to connect a send to a record in your own system? Then use the API and put your ids in the metadata.

If none of those apply, either works. Many teams end up using both: the API from their own code, and the SMTP relay for the tools they did not write.

Whichever you use, test it before it matters. Send to a safe staging address, watch what comes back for a bad address and for a rate limit, and make sure your alerts fire on those cases rather than on silence.

Key takeaways

  • SMTP and an API deliver the same message; the difference is the experience around the send.
  • A success response means "accepted", not "delivered" in both cases.
  • Idempotency, structured errors and metadata are the real reasons to prefer an API.
  • SMTP wins on compatibility and on switching providers without code changes.
  • Using both is normal and sensible.

Start with Koltrix

Your domain, one inbox, and an API that sends.

A team inbox where AI sorts and drafts (nothing is sent without your click), plus the transactional API and SMTP relay your product sends with. 7 days free, no card.

SharePost on XLinkedIn