Skip to content

A REST API shaped for machines

Everything in the dashboard, over a clean REST contract your agent can drive.

Authentication and keys

Issue an API key from the dashboard and send it on each request. Keys are scoped to a single mailbox and carry one of three roles — read, send, or admin. Set an optional expiry (30 days, 90 days, 1 year, or never), and list or revoke keys at any time; revoking takes effect almost immediately.

Idempotent writes

Send an Idempotency-Key header on mutating calls so a retried request doesn't double-execute.

cURL
curl https://mail.sairaph.com/app/api/v1/messages \
  -H "Authorization: Bearer $AGENTMAIL_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d mailbox="agent@your-domain.dev" \
  -d to="user@example.com" \
  -d subject="Your verification code" \
  -d text="Reply with APPROVE to continue."

Structured errors

Errors use a consistent envelope — type, code, message, and an optional param — modelled on Stripe's shape, so they're easy to branch on programmatically.

402 payment_required
{
  "error": {
    "type": "invalid_request_error",
    "code": "mailbox_not_found",
    "message": "No mailbox matches that address.",
    "param": "mailbox"
  }
}

Rate limits

Each API key is rate-limited per minute, scaled by your plan, and independent of your monthly outbound cap — both apply on their own. Exceed it and you get a 429 with a Retry-After header. Per-tier limits below read live from your plan.

Reading inbound

Message bodies are served from cache by default. Request a live fetch with ?live=true — rate-limited per mailbox to protect the upstream IMAP service, with a fallback to cached data if the source is briefly unreachable. A single fetched message (envelope plus body) is capped at 25 MiB.

Full reference

The complete OpenAPI reference is published as a Scalar docs site from our live schema, with interactive Swagger at /docs.

Start building