Home
Comparisons

Rust Email API: Crates, Services and Agent Mailboxes Compared

Developer comparing Rust email implementation options

There is no single "Rust email API". There are four different jobs hiding under the phrase: sending through SMTP, calling a hosted HTTP sending API, reading mail over IMAP, and giving an agent a real mailbox it can send from, receive into and search. The right choice depends on which of those you need, and on how many inboxes you will end up running.

If your app only fires receipts and password resets, a crate like lettre plus any reputable sending provider is enough. If your Rust service needs to receive and act on replies, or you are building an agent product with a mailbox per customer, you are in a different category, and the build-versus-buy maths changes quickly. This guide compares the real options so you can pick before you write the first line of glue code.

TL;DR

  • Send-only transactional mail: use lettre over SMTP, or call a provider's HTTP API with an async client such as reqwest.
  • Reading mail yourself: the IMAP crates work, but you own token refresh, threading, retries and state. That is where the time goes.
  • Self-hosted gateways (RustMailer, PRX-Email, himalaya-style tooling) suit a single team that wants full control and will run the infrastructure.
  • Agent products and multi-tenant apps: a hosted mailbox API such as Sendmux gives each agent or tenant a real inbox behind one REST API, with multi-provider outbound routing included.
  • Rust talks to any of these over plain HTTPS, so the language rarely decides the architecture. Mailbox count and reply handling do.

Table of Contents

What "Rust email API" actually covers

Most searches for this phrase land on crate lists and send-email tutorials. That makes sense, because sending is the part everybody hits first. But there are four distinct layers, and mixing them up is how teams end up with three half-integrated systems.

  1. Composition and transport: building a message and handing it to an SMTP server.
  1. Hosted sending APIs: an HTTPS endpoint that accepts your message and handles delivery.
  1. Mailbox access: reading, searching and syncing an inbox over IMAP or a provider API.
  1. Agent mailboxes: persistent inboxes with threading, routing, quotas and logs, exposed as an API.

The first two are solved problems. The third is solvable but expensive to maintain. The fourth is where AI agent products now live, and it is the layer Rust documentation says least about.

1. Lettre and SMTP: the default for sending

Lettre is the standard Rust library for creating and sending messages. It offers a message builder, pluggable transports, Unicode support, secure defaults and async support. For a monolith that sends a few thousand transactional emails a month through an SMTP relay, it is the simplest thing that works, and the Rust community's usual advice for this case, as seen in a long-running r/rust thread on transactional email, is to spawn a Tokio task that calls a mailer and move on.

What lettre does not give you:

  • Anything on the receiving side. It sends; it does not read.
  • Delivery logs, bounce handling or suppression lists. Those live with your SMTP provider.
  • A persistent outbox. If your process dies between "queued" and "accepted", you need your own database state to avoid losing or duplicating the message.

That last point matters more than it sounds. Practitioners building email agents in Rust describe a recurring set of failures: ghost messages, duplicate sends on retry and silent token expiry. The fix described in the PRX-Email documentation is an atomic outbox pipeline with claim and finalise steps, backed by SQLite persistence. It works, and it is also a few weeks of careful engineering before you have written any product logic.

2. Calling a hosted sending API from Rust

The alternative to SMTP is an HTTP API. You build a JSON body, POST it with reqwest, and let the provider handle delivery. Reqwest is the usual client: async and blocking modes, JSON and form bodies, sensible defaults. Several providers, among them Resend, a transactional email provider, SendGrid and Amazon SES, also publish Rust SDKs or are straightforward to call with plain HTTP.

This route buys you three things SMTP wrappers do not: structured error responses, webhooks for delivery events, and a provider that manages IP reputation. For a send-only app, it is usually the right call.

It stops being enough when any of these become true:

  • You need replies to land somewhere your code can read them.
  • You need to send across several providers or sender domains with quotas and failover.
  • You need each customer or agent to have its own identity, keys and logs.

At that point you are stitching a sending provider to an inbound parser to a webhook relay, with separate billing for each. That stitching is the real cost, and it is what hosted mailbox APIs exist to remove.

3. Reading mail: IMAP crates and unified clients

For inbound mail, the options split in two. Low-level protocol crates such as imap and async-imap implement RFC 3501 and its extensions: authenticate, list, fetch, search, monitor. Higher-level libraries such as himalaya and melib sit above them. Himalaya offers a shared API for mailboxes, envelopes, flags, messages and attachments across IMAP, SMTP, JMAP, Gmail's REST API and Microsoft backends.

Comparison of IMAP crates and unified mail clients

These are excellent for building a mail client or a personal tool. For a production agent they leave three problems on your desk.

Threading and quoted history. Raw MIME is noisy. Production systems map In-Reply-To and References headers to a persistent thread structure, so an agent can act on the new reply instead of re-parsing quoted history. Melib is built around exactly this kind of mail handling, but you still have to wire it into your own storage.

OAuth token upkeep. Connecting Gmail or Outlook accounts means refresh tokens that expire, get revoked or hit provider rate limits. Platform engineers describe an "OAuth death spiral", where maintaining tokens for hundreds of connected inboxes consumes more engineering time than the AI product itself, a point made in the PRX-Email overview.

Polling. An IMAP loop per inbox does not scale to a fleet. The same documentation points to centralised mailbox sync, durable local state and event-driven processing instead of constant polling.

4. Self-hosted gateways and MCP servers

A middle path is to run a Rust service that wraps mailboxes behind an HTTP API. Two examples from the research:

  • apimail is an Axum-based HTTP API for full CRUD over a single mail account: reading, flagging and searching over IMAP, parsing MIME bodies and attachments, and sending outgoing mail.
  • RustMailer is a self-hosted email middleware for IMAP, SMTP, Gmail API and Graph API, built for developers.

For agents specifically, there is also the mail-mcp server, a Rust MCP server covering IMAP, SMTP, EWS and Graph with OAuth2 and multi-account support. It follows the security pattern worth copying: give the agent a standard tool interface and constrained scopes rather than handing it app passwords and network access.

These are good options when you have one team, a handful of mailboxes and the appetite to operate the service, patch it, back up its state and keep the sending domains healthy. They are less attractive when you are provisioning a mailbox for every customer, because every tenant becomes another set of credentials and another thing that can be rate-limited or suspended by the upstream provider.

5. Hosted agent mailboxes: where Sendmux fits

Sendmux is an email API for AI agents. Each agent, customer, workspace or tenant gets a real mailbox with a real address, either on the included @myagent.mx domain or on a custom domain verified for receiving.

A Rust service can use the official Sendmux Rust SDK: one crate with Sending, Mailbox and Management modules. Install it with cargo add sendmux. It requires Rust 1.82 or newer and an async context for API calls. What you get on the other side is the stateful part that the crates above leave to you.

Mailboxes as persistent state

The Mailbox API covers messages, threads, folders, keywords, attachments, sender identities, quotas, usage and submissions. Agents read cleaned message text and HTML with quoted history stripped, and raw body endpoints remain for the exact original. For a Rust service that previously hand-rolled MIME handling, that removes a whole module.

Retrieval is built to keep payloads, and therefore LLM token costs, small:

  • GET /mailbox/messages filters on folder, thread, free-text query, sender and recipient, subject, body, arbitrary headers, size range, keywords, date range, attachments and unread state.
  • A count endpoint answers "how many" without returning rows, and search-snippets returns previews without pulling bodies.
  • Batch get, update and delete move many messages per call.
  • Sync endpoints return state tokens, so an agent polls for typed changes rather than re-listing the inbox.
  • GET /mailbox/session reports the mailbox, supported features, state tokens and request limits.

Sending from the authenticated mailbox uses POST /mailbox/messages/send. The API also has an attachment upload endpoint.

Multi-provider outbound

The sending side is where Sendmux differs from a single-provider API. You can add Custom SMTP, Gmail or Outlook / Microsoft 365 accounts, or use the included managed Amazon SES account. Delivery groups route a sending key or mailbox through a named set of providers. Provider limits and configured quotas still apply. If those protocols are new to you, our SPF, DKIM and DMARC setup guide walks through them.

For multi-tenant products, plan how to separate customer access. The platform overview is a useful starting point.

Side-by-side comparison

OptionSendsReceivesPer-tenant mailboxesYou operateBest for
lettre + SMTP relayYesNoNoOutbox, retries, logsSimple transactional mail
Hosted sending API + reqwestYesVaries by providerNoWebhooks, parsingSend-only apps
imap / async-imap / himalaya / melibVia SMTPYesDIYTokens, sync, threadingMail clients, personal tools
Self-hosted gateway (apimail, RustMailer, mail-mcp)YesYesAccount by accountThe service itselfOne team, few mailboxes
SendmuxYes, multi-providerYes, persistent mailboxesYesYour integration codeAgent fleets, multi-tenant SaaS

Read the table by the last two columns. The further right you look, the less infrastructure sits on your side, and the more your Rust code is just product logic.

What it costs

Check the pricing page when modelling your costs.

A practical way to compare: add up what a DIY stack costs in a month, including the sending provider, an inbound parsing service, hosting for your IMAP workers and, hardest to price, the engineer-hours spent on token refresh and suspended accounts. Check current terms on the pricing page before you model your costs.

A decision framework

Ask these in order.

  1. Do you need to receive mail at all? If not, stop at lettre or a hosted sending API.
  1. How many mailboxes will you run in twelve months? One to five: a self-hosted gateway is reasonable. Dozens or more, one per customer: hosted.
  1. Do agents act on replies? Then you need clean, threaded content and change-sync, not raw MIME and polling.
  1. Do you send across more than one provider or domain? Then you need quotas, rotation and failover, which are tedious to build well.
  1. Who handles deliverability? Protocol hygiene across SPF, DKIM and DMARC and provider reputation is hard to manage by hand at scale, so offload delivery and keep inbox and context logic in your own code. That is the advice in the RustMailer repository itself.

If you answered "hosted" to two or more, the quickest test is to start on the free plan and wire one agent through the agent builder guide.

Our view: Rust is not the hard part

We talk to a lot of teams building agent products, and the pattern repeats. The first version goes fast: an SMTP crate, an IMAP loop, a Gmail token in an environment variable. It demos well. Then the second customer arrives, then the fiftieth, and the project quietly becomes an email infrastructure company that happens to have an AI feature.

Our view: Rust is not the hard part, overview diagram

We built Sendmux around persistent mailbox state. An agent should be able to ask how many unread messages match a filter without downloading them, read the new reply without the quoted thread, and pick up from a state token after a restart. When we say retrieval precision, we mean fewer tokens per decision and fewer ways for an agent to act on stale or duplicated context.

Rust teams tend to be the most wary of outsourcing this, and that instinct is healthy: you care about correctness, exactly-once behaviour and owning your failure modes. Our advice is to spend that rigour where it differentiates you. Keep the agent logic, the permissions model and the business rules in your own code. Hand the mailbox, the provider routing and the delivery plumbing to something built for it. If you later outgrow that, the REST boundary makes it a contained migration rather than a rewrite.

Try it with one agent

If you are building an agent in Rust and want it to have a real inbox, start on the Sendmux free plan and give one agent a mailbox on @myagent.mx. Move to a custom domain once the flow works. For the full picture of how inboxes, routing and sending fit together, the email inbox for AI agents guide is the place to go next.

Sources

Frequently Asked Questions

Is there an official Sendmux Rust crate?

Yes. The official Sendmux Rust SDK is the `sendmux` crate, with Sending, Mailbox and Management modules. Install it with `cargo add sendmux`. It requires Rust 1.82 or newer and an async context for API calls.

Should I use lettre or an HTTP email API?

Use lettre when you already have an SMTP relay and only send. Use an HTTP API when you want structured errors, webhooks and delivery events. Neither reads incoming mail, so if replies matter, you need a mailbox layer as well.

Can I run IMAP polling for an AI agent in production?

You can, but expect to build token refresh, retry-safe sending, threading and durable state yourself. Teams that do this at scale typically move to centralised sync and event-driven processing, or to a managed mailbox API, rather than one polling loop per inbox.

How do I keep an agent's email access safe?

Prefer OAuth2 with constrained scopes over IMAP or SMTP app passwords, and expose email through a standard interface such as an MCP server rather than giving the agent direct network access, as the mail-mcp project recommends.