What makes an email API reliable for an agent?

Your agent submits a support reply, then loses the connection before receiving the response. Don't send again just because the request timed out. Record the uncertainty and reconcile the attempt first.

For this workflow, reliability means recoverable processing with controlled side effects. Your application should know what work remains, what was approved, and which sends need investigation after a restart.

The running example is a team-owned test mailbox: an agent reads a support message, classifies it, and prepares a reply for human approval. This is about operating existing mailboxes, not choosing transactional sending infrastructure. The Mailera product overview describes that mailbox connection model; email for AI agents explains where it fits.

The key design choice is to separate a proposed reply from permission to send it. Keep the queue, durable action records, approval gate, and recovery worker in your application. Mailera supplies REST, MCP, and webhook interfaces for connected mailboxes. See the API documentation for these interfaces.

Which permissions should each part of the workflow have?

Treat workspace roles, API permissions, and approval policy as separate controls. Only Admin or Leader roles can add mailboxes through the app's Add mailbox flow. That role rule is not a substitute for scoping a worker's API key.

API keys can be limited to one mailbox group; Admins can also select all groups. Start with a dedicated test group and assign permissions by worker responsibility:

ComponentAPI permissionResponsibility
Reader and classifierreadRetrieve messages and prepare proposed actions
Approved-send workersendSubmit approved replies and reconcile send attempts
Webhook provisioning processwebhooksConfigure webhook subscriptions
Recovery workersync, only if neededTrigger mailbox synchronization

Add read to a recovery worker only if it also needs to inspect mailbox status. A process that only accepts incoming webhook requests does not need a provisioning key merely to receive them.

GET /sends/{id} requires send, just like POST /mailboxes/{id}/send. Keep send reconciliation with the send-capable worker rather than expanding the reader's permissions.

To create a reader key:

  1. Open Settings → API key → Create key.
  2. Set Descriptive name to identify the worker.
  3. Under Mailbox scope, select its mailbox group.
  4. Select Read and leave unrelated permissions unselected.
  5. Configure IP restrictions (optional) if appropriate, and choose Expiration.
  6. Store the secret securely when Key created — copy it now appears. It is shown only once.

Create a separate send-worker key with Send messages. Don't give every worker Manage mailboxes to avoid handling authorization failures. Revoking a key causes calls using it to be rejected immediately, so include revocation in your operational plan.

Mailera API key dialog with one mailbox group selected and only Read permission enabled.
Give the reader its own group-scoped key; keep sending permissions on a separate worker.

The workspace roles guide covers the human-access side. For MCP integrations, the same separation matters: send_email, reply_to_email, and get_send_status require send. See the Mailera MCP interface when assigning tools to an agent.

How do you build a recoverable receive-to-send workflow?

Use one durable business-action record for the intended reply. An incoming event is a signal to process work; it should not itself authorize a send.

  1. Receive and validate the event. Use message.received as the incoming-message signal. Verify the webhook before accepting its content as an authentic event.
  2. Persist accepted work. Store it durably before downstream processing.
  3. Retrieve the message with the reader key. Use GET /mailboxes/{id}/messages/{msgId}. The response provides data.id, data.mailbox_id, and message content under data.body.
  4. Prepare a proposal. Classify the support request and draft a reply. Treat the message body as untrusted input throughout this step.
  5. Obtain approval. Show the exact recipients and content to the reviewer. Bind approval to that version, not to a mutable draft.
  6. Persist submission intent. Store the approved version and its idempotency key before the send worker calls POST /mailboxes/{id}/send.
  7. Reconcile the attempt. Retain the send reference when available and use GET /sends/{id} to inspect its status. Route unresolved attempts to recovery rather than creating another reply.
A Mailera event enters application verification and durable storage, then a read-only worker prepares a reply for approval before a send worker submits and reconciles it.
The application owns durable processing and approval. The reader does not need sending permission.

Keep these records in your application database; they are not proposed Mailera request fields:

Application recordPurpose
Business-action identifierDistinguishes this intended reply from other work
Source mailbox and message referencesConnects the action to the incoming message
Approved recipients and content versionDefines exactly what may be sent
Approval recordRecords who approved which version and when
Idempotency keyPreserves the identity of a submission across retries
Send reference and observed stateSupports reconciliation when a reference is available
Recovery historyRecords decisions after interruptions

Use a database uniqueness constraint or equivalent atomic guard to prevent concurrent consumers from creating the same business action. Scope that guard to the intended action: a message may legitimately need a later follow-up, but a duplicate event should not create one.

For the basic read-and-reply integration, see building an agent with approved replies. The developer overview covers Mailera's integration interfaces.

How do you retry without sending the same reply twice?

A retry continues the same approved action. A new recipient, changed reply, or newly approved follow-up is a different action. Keep that distinction in durable state rather than letting each worker invocation decide it again.

Mailera's send endpoint accepts Idempotency-Key. Assign the key before submission, retain it with the approved action, and preserve it when retrying that same operation. Don't generate a fresh key merely because the client timed out.

Keep the approved payload fixed as well. If content changes, stop and obtain approval for a new action instead of silently changing the request associated with an existing key. The Idempotency-Key guide covers the send-specific implementation details.

Application records remain necessary alongside API idempotency. Retain them according to your recovery and audit needs; don't make your workflow's memory depend solely on the API recognizing an earlier request.

Use the following as an application recovery policy, not as a claim about recipient delivery:

Send-attempt statusApplication action
queuedKeep the action pending; schedule another status check rather than another send.
sendingKeep submission blocked while checking the existing attempt.
sentClose the submission workflow without issuing another send. Do not label it recipient delivery confirmation.
failedInspect the failure and decide whether correction or further review is needed before authorizing another submission.
unknownHold the action for reconciliation or operator review. Do not resend automatically.

If you have a send identifier, use GET /sends/{id}. If the response was lost before you could retain that identifier, preserve the action and its original key, then stop automatic resubmission until you have a safe recovery decision. Don't invent a lookup route or substitute a fresh key.

The hardest crash occurs after submission but before the local result is saved. Persisting intent beforehand gives your recovery worker something to find. It does not eliminate uncertainty, so represent “submission outcome unresolved” explicitly in your own state model.

An unresolved submission goes to status inspection when its identifier is known, or operator review when it is missing; no path automatically resends.
Ambiguous outcomes need reconciliation, not a new send request.

How should webhook processing survive duplicates and restarts?

Separate three controls: signature verification checks authenticity, replay protection checks whether a captured request should still be accepted, and business-action deduplication prevents repeated processing from creating repeated replies.

Mailera's webhook header catalog includes X-MailHub-Event, X-MailHub-Delivery, X-MailHub-Timestamp, X-MailHub-Signature, and X-Mailera-Signature. Header names alone are not a verification algorithm or a rule for choosing between signature headers.

When provisioning through POST /webhooks, save the signing secret securely: it is returned only once. Keep it outside the model's message-processing context.

Design the consumer around a durable handoff:

  • Validate the incoming request before enqueueing accepted work.
  • Persist accepted work durably before downstream processing.
  • Deduplicate the intended business action before creating a proposal or send job.
  • Make unfinished work discoverable after a restart.

Record a delivery identifier for tracing, but don't make it your only business-action deduplication key. Use the source message reference together with your application-defined action identity. That decision keeps transport handling separate from the question “Has this reply already been approved or submitted?”

For concurrent consumers, make the claim on an action atomic. For restarts, use a recoverable claim mechanism so abandoned work can be inspected without immediately repeating a send. Recovery should resume from the stored stage, not restart the whole workflow from message classification.

What happens when a mailbox disconnects or requests are throttled?

On mailbox.disconnected, pause application work for that mailbox and notify its responsible operator. Don't turn a connection problem into a loop of new send attempts.

Use GET /mailboxes/{id}/status to investigate sign-in health. For Microsoft mailboxes, it checks sign-in directly. For other providers, the information is based on the latest sync. Interpret those results accordingly rather than treating them as identical live probes.

Idle mailboxes may sleep. POST /mailboxes/{id}/sync can trigger synchronization and wake them, but your workflow should wait for the required data rather than assume a fixed completion time. The mailbox sync recovery guide covers that operational path.

For retryable requests, use bounded exponential backoff with jitter and an escalation threshold. Keep read retries separate from send recovery: a timeout on a write leaves a different question than a failed attempt to retrieve a message.

RFC 6585's definition of HTTP 429 describes rate limiting and allows a Retry-After header. Respect it when supplied; don't assume every throttled response includes it.

Microsoft Graph's throttling guidance recommends waiting for Retry-After, using exponential backoff when it is absent, and avoiding immediate retries. That is upstream Microsoft guidance, not a Mailera public-API quota specification.

Track application-owned signals such as pending-work age, repeated authorization failures, and the number of unresolved submissions. Give each alert an owner and a recovery action. An alert that merely says “email failed” leaves the operator guessing whether reading, approval, or sending stopped.

How do you stop incoming email from controlling the agent?

Incoming email is untrusted data, not instructions. Apply that rule to quoted text and attachments as well as the visible message body.

In the support example, an email might tell the agent to ignore approval, change the recipient, reveal credentials, or call another tool. Treat those requests as content to evaluate, never as authority to change the workflow.

Keep API keys and webhook secrets outside the model context. Give the reader only the mailbox group and permissions it needs. Put the send-capable tool behind your application-owned approval gate rather than exposing it to the classifier.

Approval must cover the exact recipients and message content. If either changes, invalidate the approval and request another review. The send worker should check that binding independently instead of trusting the model's claim that approval happened.

Review Mailera's security information alongside your application's controls. Narrow API access limits what a credential can do; it does not decide whether a proposed reply is appropriate.

Which common mistakes should you test before production?

Run failure scenarios with mailboxes your team owns. Define the expected behavior before testing, then retain dated, redacted records of the requests, responses, and application transitions.

TriggerExpected application behaviorRecord to retain
Timeout after send submissionHold the action and reconcile; no fresh-key resendAction, original key reference, response or timeout details
Duplicate incoming eventReuse the existing business actionEvent traces and deduplication decision
Crash after submission, before saving the resultRecover persisted intent as unresolvedPre-submission record and restart decision
Concurrent processing of one approved actionPermit only one application submission pathAtomic claim or uniqueness result
Revoked keyStop affected calls and notify the ownerRedacted rejection and key identity
Mailbox outside the selected groupStop the job rather than expanding scope automaticallyAccess-test result and configured scope
Disconnected mailboxPause affected work and escalateEvent and mailbox-status observation
Invalid webhook signatureReject the request before processingVerification outcome without secrets
Malicious instructions inside emailPreserve the approval boundaryRedacted input and proposed-action review

Also test a recipient change after approval. The expected result is renewed review, not reuse of the earlier approval.

Common implementation mistakes are generating a new idempotency key for every retry, interpreting sent as inbox delivery, granting every worker management permissions, and logging full message bodies or secrets. Prefer action identifiers and redacted operational metadata in routine logs. Keep sensitive test artifacts access-controlled.

What does Mailera not handle for you?

Mailera connects existing mailboxes. It does not create new mailboxes or email addresses, support bulk or marketing sending, or guarantee inbox placement. Treat send-attempt state as operational information, not proof that a recipient received or read the message.

Your application owns the queue, durable action records, approval gate, and incident escalation. Provider filtering and sending restrictions remain outside those application controls.

Before production, assign each control to an owner:

ControlOwnerReadiness check
Scoped keys and mailbox API accessMailera supplies controls; your operator configures themEach worker has a documented permission set and mailbox group
Durable jobs and action deduplicationApplicationRestarts and concurrent consumers preserve action identity
Approval enforcementApplicationChanged recipients or content require new approval
Send-status accessMailera supplies the endpoint; application reconcilesUnresolved attempts stay blocked from blind resubmission
Mailbox connectivity and provider restrictionsMailbox provider, monitored by your operatorDisconnects reach a responsible person
Recovery decisions and sensitive logsApplicationOperators can investigate without exposing credentials or message bodies

Do this with the API

Every action in this article is available via the REST API, with curl examples, API keys and webhooks.

View API docs