agentmail-rs
Unofficial. This is a community Rust client, not affiliated with or endorsed by AgentMail. AgentMail ships official Python and TypeScript SDKs; this crate fills the Rust gap. Wire shapes track AgentMail's public OpenAPI spec (API v0), which may change; pin a version and read the changelog.
A typed, async client for AgentMail, the email API
for agents, with full coverage of the AgentMail API v0 at every scope:
- Inboxes: create / list / get / update / delete
- Threads: list / filter / search / get / update / delete
- Messages: send / list / filter / search / get / update / delete, reply, reply-all, forward, raw source, batch get / update
- Drafts: create / list / get / update / delete / send
- Attachments: fetch metadata and download bytes (presigned)
- Webhooks: create / list / get / update / delete, plus optional Svix signature verification
- Domains: create / list / get / update / delete, verify, zone file
- Pods, allow/block lists, metrics (events + usage), inbox events, API keys, organization, and agent sign-up / verify
- Pagination on every list call,
list_all_*helpers that drain it, and automatic retries with exponential backoff
Scopes
Resources that AgentMail exposes at more than one scope (threads, webhooks, lists, domains, metrics, API keys, drafts, inboxes) are reached through a typed scope handle so the compiler rejects an operation a scope doesn't support:
# async
Inbox-only resources (messages, drafts, inbox events) live on
client.inbox(id); account-global ones (pods, organization, auth, agent) are
flat on Client.
Deliberately small: reqwest + serde + thiserror (plus tokio for retry
backoff), with permissive deserialization (unknown fields are ignored) so API
additions don't break you. Requests carry a 30-second default timeout. TLS is
rustls with the ring provider (no OpenSSL, no aws-lc-rs, no C toolchain).
The client installs ring as the process default at construction; if your
application already installs a crypto provider, that choice is respected.
Features
retries(default): automatic retries with backoff. Turn it off withdefault-features = falseto drop the directtokiodependency and make every request a single attempt; tune it withClient::with_retry_policy.webhook-verify(off by default):verify_webhook_signaturefor Svix-signed webhook deliveries. Addsring(already the rustls provider) andbase64.
Install
The crate publishes as agentmail-rs (the bare agentmail name was taken) but
imports as agentmail. MSRV is Rust 1.86.
Usage
# async
Client::from_env() reads AGENTMAIL_API_KEY (and optional AGENTMAIL_BASE_URL
for the EU region or a mock server). For explicit config, use Client::new(key, base_url).
Testing
The unit and mock-server tests (cargo test) run offline. For a live smoke
test that creates, exercises, and lists real inboxes against the API:
AGENTMAIL_API_KEY=...
Receiving mail? The webhook example verifies a Svix-signed delivery end to end:
Parity
This crate binds the entire AgentMail API v0 surface the official Python/TypeScript SDKs expose, at all three scopes (organization, inbox, pod) via the typed scope handles above.
Two things the official SDKs also lack and this crate treats as extras: there
is no WebSocket / realtime API to bind (AgentMail exposes none), and the
Svix webhook signature verification helper here goes slightly beyond the
SDKs (behind the webhook-verify feature). Beyond the SDKs, the list_all_*
helpers drain pagination for you.
Changes land in the changelog.
Contributing
Issues and PRs are welcome. Wire shapes track AgentMail's
OpenAPI spec, so when adding or
changing an endpoint, match the spec and add a wiremock test under
tests/http/ (the suite runs offline: cargo test --all-features). If you need
a scope-mirrored endpoint variant that isn't bound yet, open an issue.
License
Licensed under either of MIT or Apache-2.0 at your option.