Skip to main content

Crate agentmail

Crate agentmail 

Source
Expand description

Unofficial typed Rust client for AgentMail, the email API for agents (official SDKs exist for Python and TypeScript; this fills the Rust gap).

Wire shapes follow AgentMail’s OpenAPI spec (docs.agentmail.to/openapi.json, API v0), with full coverage of the surface the official SDKs expose: inboxes, threads, messages, drafts, attachments, webhooks, domains, pods, allow/block lists, metrics, API keys, and agent onboarding. Everything deserializes permissively: unknown fields are ignored, optional fields default, so spec additions don’t break callers.

Resources that exist at more than one scope (threads, webhooks, lists, domains, …) are reached through a scope handle (Client::org, Client::inbox, or Client::pod), so the compiler rejects an operation the scope doesn’t support. Inbox-only resources (messages, drafts) live on Client::inbox.

let client = agentmail::Client::from_env()?; // AGENTMAIL_API_KEY
let inbox = client
    .org()
    .create_inbox(agentmail::CreateInbox {
        username: Some("my-agent".into()),
        display_name: Some("My Agent".into()),
        ..Default::default()
    })
    .await?; // my-agent@agentmail.to

client
    .inbox(&inbox.inbox_id)
    .send_text("someone@example.com", "Hello", "From an agent's own inbox.")
    .await?;

§Coverage

Inboxes (incl. search and authorization), threads, messages (send/reply/forward/raw/batch, open tracking), drafts (incl. attachment deltas), attachments, webhooks (incl. custom delivery headers), domains (incl. provider setup links), pods, allow/block lists, metrics (events/usage/rates), inbox events, calendars, accounts, apps, API keys (bearer and public-key), organization, auth, and agent onboarding. Every list call is paginated (Page), and requests carry automatic retries with backoff.

Not bound as REST: the official SDKs’ WebSocket / realtime event stream is bound behind the websockets feature (see RealtimeStream); the REST surface here is complete without it.

§Features

  • retries (default): automatic retries with exponential backoff. Turn it off with default-features = false to drop the direct tokio dependency; tune it with Client::with_retry_policy.
  • webhook-verify (off by default): verify_webhook_signature for Svix-signed webhook deliveries. Adds ring (already the rustls provider) and base64.
  • websockets (off by default): Client::connect_realtime for the realtime event stream, so agents without a public webhook URL can receive mail. Adds tokio-tungstenite (rustls, webpki roots) and futures-util; see the RealtimeStream type.

Structs§

Account
A human account (an app connection): who signed in to which app, through which inbox, and when.
AccountList
One page of accounts from list_accounts.
AccountsListFilters
List filters for list_accounts (includes pagination, like the other filter structs).
AgentAttachHuman
Request body for agent_attach_human: email a claim link that connects a human to this agent’s organization.
AgentAttachHumanResult
The response to agent_attach_human.
AgentSignup
Request body for agent_sign_up: start onboarding a new agent, which emails a one-time code to human_email when given. username is the only required field; without human_email the inbox is created unattached to a human (attach one later with crate::Client::agent_attach_human).
AgentSignupResult
The response to agent_sign_up: the new organization, inbox, and its API key.
AgentVerifyResult
The result of agent_verify.
ApiKey
An API key, as the API returns it. The wire shape is a oneOf over bearer keys and public_key credentials; every field defaults so both parse. The secret material itself is never returned here (see CreatedApiKey).
ApiKeyCreator
The agent that created a public_key API key.
ApiKeyList
One page of API keys from list_api_keys_page.
App
An app that can connect to AgentMail inboxes, from the app directory.
AppAccountList
One page of an app’s accounts from list_app_accounts.
AppList
One page of apps from list_apps.
AppSearchList
One page of apps from search_apps (no pagination cursor).
AppsListFilters
List filters for list_apps (includes pagination).
Attachment
Attachment metadata as returned in message, thread, and draft responses. download_url (a short-lived presigned URL) is populated only by the attachment-download endpoints; the other fields describe the attachment in list and get responses.
AuthorizeInbox
Body for authorize_inbox: complete a human authorization started in the browser. The auth_token comes from that flow.
AuthorizeInboxResult
The response to authorize_inbox.
BatchGetMessages
Request body for batch_get_messages.
BatchGetMessagesResponse
Response to batch_get_messages.
BatchUpdateMessages
Request body for batch_update_messages: apply the same label changes to many messages at once.
BatchUpdateMessagesResponse
Response to batch_update_messages.
BouncePayloadwebsockets
Bounce details, from message.bounced.
Calendar
An inbox’s calendar, from get_calendar / update_calendar.
CalendarAttendee
An attendee on an event.
CalendarEvent
A calendar event, as the API returns it.
CalendarEventCreatedEventwebsockets
A decoded event frame; see the module docs for the protocol.
CalendarEventDeletedEventwebsockets
A decoded event frame; see the module docs for the protocol.
CalendarEventEndingEventwebsockets
A decoded event frame; see the module docs for the protocol.
CalendarEventList
One page of occurrences from get_agenda or list_event_instances.
CalendarEventMutation
The response to an event create/update: the mutated event plus the operation id (used by the API’s event stream to ack the change).
CalendarEventPreviouswebsockets
A calendar event’s state before an update, all fields optional.
CalendarEventRespondedEventwebsockets
A decoded event frame; see the module docs for the protocol.
CalendarEventStartingEventwebsockets
A decoded event frame; see the module docs for the protocol.
CalendarEventUpdatedEventwebsockets
A decoded event frame; see the module docs for the protocol.
CalendarEventsQuery
Windowing and pagination for get_agenda and list_event_instances.
Client
An authenticated handle on the AgentMail API. Cheap to clone-ish (it owns a pooled reqwest::Client); construct once and share by reference.
ComplaintPayloadwebsockets
Complaint details, from message.complained.
ConnectApp
Body for connect_app: start a human’s connection to an app. The human opens ConnectAppResult::magic_url and approves; the API key id in the result is the connection’s credential handle.
ConnectAppResult
The response to connect_app.
CreateApiKey
Request body for create_api_key. The default (no public_key) mints a bearer key; setting public_key registers a public_key credential instead. The full secret of a bearer key is returned exactly once, in CreatedApiKey::api_key.
CreateCalendarEvent
Body for create_calendar_event. title, start, and end are required by the API.
CreateDomain
Request body for create_domain.
CreateDraft
Request body for create_draft. At least one recipient or a reply/forward-of reference and one of text/html are required by the API.
CreateInbox
Request body for create_inbox. All fields optional; the API generates a username when none is given.
CreateListEntry
Request body for create_list_entry.
CreatePod
Request body for create_pod. All fields optional.
CreateWebhook
Request body for create_webhook.
CreatedApiKey
The response to create_api_key. The full api_key secret is returned exactly once, here; store it now, as it cannot be retrieved again.
DeleteCalendarEventResult
The response to delete_calendar_event; event carries the deleted state when the API returns it.
DispatchPayloadwebsockets
Send/delivery details, from message.sent and message.delivered.
Domain
A sending domain, as the API returns it.
DomainList
One page of domains from list_domains_page.
DomainSetupLink
The provider setup link for a domain, from get_domain_setup_link. When DomainSetupLink::supported is false the registrar/provider flow isn’t available and DNS records must be configured manually.
DomainVerifiedEventwebsockets
A decoded event frame; see the module docs for the protocol.
Draft
A draft message, as the API returns it. List items are a subset of the full get-draft shape; every optional field defaults so both parse.
DraftList
One page of drafts from list_drafts_page.
EventRecipientwebsockets
A per-recipient delivery status, from bounce events.
Identity
Who the current API key authenticates as, from auth_me.
Inbox
An agent-owned inbox, as the API returns it.
InboxEvent
An entry in an inbox’s audit log (label changes, deliveries, etc.).
InboxEventList
One page of inbox events from list_inbox_events_page.
InboxList
One page of inboxes from list_inboxes_page.
InboxScope
A single inbox scope (/v0/inboxes/{inbox_id}/...).
ListEntries
One page of list entries from list_list_entries_page.
ListEntry
A single allow/block list entry.
Message
A message as the API returns it. List and search items are a subset of the full get-message shape; every non-id field defaults so all three parse.
MessageBouncedEventwebsockets
A decoded event frame; see the module docs for the protocol.
MessageComplainedEventwebsockets
A decoded event frame; see the module docs for the protocol.
MessageDeliveredEventwebsockets
A decoded event frame; see the module docs for the protocol.
MessageList
One page of messages from list_messages_page.
MessageListFilters
Filters for list_messages_filtered and search_messages_page. Pagination fields (limit, page_token) live here because they share the same query-parameter namespace as the filter fields.
MessageOpenedEventwebsockets
A decoded event frame; see the module docs for the protocol.
MessageReceivedEventwebsockets
One event off the wire, decoded.
MessageRejectedEventwebsockets
A decoded event frame; see the module docs for the protocol.
MessageSentEventwebsockets
A decoded event frame; see the module docs for the protocol.
MetricBucket
One time-bucket of an event metric.
MetricsQuery
Query parameters for the metrics endpoints (get_metrics_events, get_metrics_usage, get_metrics_rates). types filters by event/usage/rate type; leave it empty for all. window is only meaningful for rates (the bucket the rate is computed over, in seconds).
OpenPayloadwebsockets
Recipient-open details, from message.opened.
OrgScope
The organization scope (top-level, /v0/...), spanning every inbox.
Organization
The organization the current API key belongs to, from get_organization.
Page
Pagination controls for the list_*_page calls. Default is the API’s own defaults (first page, server-chosen page size).
Pod
A pod, a container that owns inboxes and other resources.
PodList
One page of pods from list_pods_page.
PodScope
A single pod scope (/v0/pods/{pod_id}/...).
PublicKeyMaterial
The public-key material bound to a public_key API key (JWK plus its RFC 7638 thumbprint), as the API returns it.
RatePoint
One time-bucket of a rate metric (bounce/complaint percentages).
RawMessage
The presigned download for a message’s raw RFC 822 source, from get_raw_message. Fetch the bytes with download_raw.
RealtimeStreamwebsockets
An open realtime stream. Send one Subscribe (done for you by Client::connect_realtime), then poll RealtimeStream::next_event.
Recurrence
Recurrence rule and exceptions on an event. rdates entries are either an RFC 3339 timestamp or a {start, end?, duration?} object, so they are kept as raw JSON.
RejectPayloadwebsockets
Rejection details, from message.rejected.
ReplyToMessage
Request body for reply_to_message and reply_all_to_message. to overrides the derived recipients when non-empty; at least one of text/html is required by the API.
RespondToCalendarEvent
Body for respond_to_calendar_event: the inbox’s reply to an invite.
RetryPolicyretries
How the client retries transient failures. Applied to every request at the one HTTP chokepoint. Default retries twice with exponential backoff.
Scoped
A Client bound to a Scope. Returned by Client::org, Client::inbox, and Client::pod; the resource methods it exposes depend on which capability traits the scope S implements.
SendAttachment
An attachment to include on an outgoing message or draft. Supply the bytes inline as base64 content, or a url for the API to fetch; set content_id to reference the attachment inline from the HTML body.
SendMessage
Request body for send_message. At least one recipient in to and one of text/html are required by the API.
SentMessage
The API’s acknowledgement of a send.
Subscribewebsockets
A subscribe request: which events, and for which inboxes or pods. Empty filters mean “everything the key can see”.
Subscribedwebsockets
The server’s acknowledgement of a Subscribe frame.
Thread
A conversation thread. List items omit messages; the get-thread shape includes them and search results carry highlights; every optional field defaults so all three parse into this one type.
ThreadList
One page of threads from a list or search call.
ThreadListFilters
Filters for list_threads_filtered and search_threads_page. Pagination fields (limit, page_token) share the same query-parameter namespace as the filters.
UpdateAccount
Body for update_account. Fields left None stay unchanged.
UpdateApiKey
Body for update_api_key. Fields left None stay unchanged.
UpdateCalendarEvent
Body for update_calendar_event. Fields left None stay unchanged; there is no way to set a field back to null from this client (the API accepts nulls for description/location/metadata/recurrence, but None here means “leave alone”, matching crate::UpdateDraft).
UpdateDomain
Request body for update_domain. Fields left None stay unchanged.
UpdateDraft
Request body for update_draft. Every field is optional; omitted fields are left unchanged on the server. Pass Some(vec![]) to clear a recipient field; pass None to leave it alone.
UpdateInbox
Request body for update_inbox. Fields left None are omitted and stay unchanged; set metadata to Some(Value::Null) to clear it.
UpdateMessage
Request body for update_message.
UpdateThread
Request body for update_thread: labels to add and/or remove.
UpdateWebhook
Request body for update_webhook. Every field is optional; leave a field empty to keep it unchanged. Inbox and pod targeting is edited by delta (add/remove lists) rather than by replacing the whole set.
UpdateWebhookHeaders
Body for update_webhook_headers: headers to set or replace, plus names to remove. Applied to every delivery of that webhook.
UpdatedMessage
The API’s response to update_message: the message id and its labels after the update.
UpdatedThread
The API’s response to update_thread: the thread id and its labels after the update.
UsagePoint
One time-bucket of a usage metric.
VerificationRecord
A single DNS record to publish for a domain.
Webhook
A webhook subscription, as the API returns it.
WebhookHeaderNames
The header names configured on a webhook, from get_webhook_headers (values are never returned).
WebhookList
One page of webhooks from list_webhooks_page.

Enums§

Consistency
Read-staleness control for calendar reads. primary (the API default) reads the authoritative store; eventual may serve a replica.
DurationMode
How an event’s duration_value is interpreted.
EntryType
Whether a list entry is an address or a whole domain.
Error
Everything that can go wrong talking to AgentMail.
EventKind
Whether an event occurs once or as part of a series.
EventSource
Where an event came from.
EventStatus
Confirmation state of an event.
ListDirection
Which traffic direction a list governs. A path input only (there is no wire value to decode), so it has no unknown variant.
ListKind
Whether a list allows or blocks its entries. A path input only, so it has no unknown variant.
MutationMode
Which occurrences a series mutation applies to.
RealtimeEventwebsockets
One frame from the stream.
ResponseStatus
The organizer’s response state on an event the inbox was invited to.
ScopeType
What an API key is scoped to.
SignatureErrorwebhook-verify
Why webhook verification failed. Verification never “passes open”: a missing or malformed secret, header, or signature is always an error.

Constants§

DEFAULT_BASE_URL
The production API host. Override with Client::new(key, base_url) for the EU region (https://api.agentmail.eu) or a mock server.
DEFAULT_TIMEOUT
The per-request timeout applied by Client::new (connect + response).
DEFAULT_WEBHOOK_TOLERANCEwebhook-verify
The Svix-recommended timestamp tolerance (5 minutes).
DEFAULT_WEBSOCKET_URLwebsockets
The production realtime host. See the module docs for how the URL is derived and overridden.

Traits§

ApiKeys
Scopes with API keys (org / inbox / pod).
Domains
Scopes with domains (org / pod). Inboxes have no domains.
Drafts
Scopes with readable drafts (org / inbox / pod). Draft writes (create, update, delete, send) are inbox-only and live on Scoped<InboxScope>.
Inboxes
Scopes that contain inboxes (org / pod): list, create, get, update, delete inboxes within the scope. A pod owns its inboxes; the org owns all of them.
Lists
Scopes with allow/block lists (org / inbox / pod).
Metrics
Scopes with metrics (org / inbox / pod).
Scope
A scope’s URL prefix. Implemented by OrgScope, InboxScope, and PodScope.
Threads
Scopes with threads (org / inbox / pod).
Webhooks
Scopes with webhooks (org / inbox / pod).

Functions§

verify_webhook_signaturewebhook-verify
Verify a webhook delivery’s signature.
verify_webhook_timestampwebhook-verify
Reject deliveries whose svix-timestamp is more than tolerance away from now (in either direction), the standard defense against replayed payloads. See DEFAULT_WEBHOOK_TOLERANCE.

Type Aliases§

ApiKeyPermissions
An API key’s permission flags, keyed by permission name (e.g. message_send, calendar_event_create). Modeled as a map so permission additions don’t require a client release; unknown names are preserved.
MetricsEvents
Event metrics keyed by event type (e.g. message.received).
MetricsRates
Rate metrics keyed by rate type (bounce, complaint).
MetricsUsage
Usage metrics keyed by usage type.