All Your InboxesStart free

API, webhooks & MCP

The same product, reached from code. Send from any address you connected, get every received email pushed to you, answer it in-thread from the business address, and give an AI agent a safe, scoped way to do the same.

1 · Authentication & keys

Create a key in the panel under Developers (or via POST /v1/api-keys with a manage key). Keys belong to one organization and carry scopes: send, read, reply, manage. Send it as a bearer token:

Authorization: Bearer ayi_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Base URL: https://allyourinboxes.com/api/v1. Every error is a JSON body { statusCode, name, message } with Resend's error names (validation_error, missing_api_key, rate_limit_exceeded, monthly_quota_exceeded…), so existing error handling keeps working.

2 · Send an email (Resend-compatible)

Same request body as Resend's POST /emails. The only rule: from must be an inbox you connected (or any address on a catch-all domain) with sending enabled.

curl https://allyourinboxes.com/api/v1/emails \
  -H "Authorization: Bearer ayi_live_…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1234" \
  -d '{
    "from": "Acme Support <support@acme.com>",
    "to": ["customer@example.com"],
    "reply_to": "support@acme.com",
    "subject": "Your order shipped",
    "html": "<p>On its way.</p>",
    "attachments": [{ "filename": "invoice.pdf", "content": "<base64>" }]
  }'
# → { "id": "…" }

Using the Resend Node SDK? Point it at us and keep the code:

import { Resend } from "resend";
const resend = new Resend("ayi_live_…", { baseUrl: "https://allyourinboxes.com/api/v1" }); // or RESEND_BASE_URL=https://allyourinboxes.com/api/v1
await resend.emails.send({ from: "support@acme.com", to: "customer@example.com", subject: "Hi", text: "Hello" });

Also available: POST /emails/batch (up to 100, index-aligned response), GET /emails/:id (status), GET /emails (recent sends). Threading: add "in_reply_to": "<received email id>" and we set In-Reply-To/References for you.

3 · Receive: webhooks

Add a URL under Developers (or POST /v1/webhooks). Choose events: email.received, email.blocked, reply.sent, email.sent, email.failed. Optionally limit to specific inboxes. Unlike metadata-only providers, email.received carries the text body and signed attachment links, so one request is usually all you need:

POST https://your-app.example/webhooks/mail
webhook-id: dlv_…            webhook-timestamp: 1725700000
webhook-signature: v1,MEUCIQ…   content-type: application/json

{
  "type": "email.received",
  "created_at": "2026-09-07T10:12:00.000Z",
  "data": {
    "email_id": "cm…", "inbox_id": "cm…", "inbox": "support@acme.com", "project": "Acme",
    "from": "Jane <jane@example.com>", "from_address": "jane@example.com", "to": "support@acme.com",
    "subject": "Refund?", "message_id": "<…@example.com>", "received_at": "…",
    "authenticated": true,
    "text": "Hi, I'd like a refund for…",
    "text_expires_at": "2026-09-08T10:12:00.000Z",
    "attachments": [{ "id": "…", "filename": "receipt.pdf", "content_type": "application/pdf", "size": 48213,
                      "download_url": "https://allyourinboxes.com/api/v1/attachments/…?exp=…&sig=…", "expires_at": "…" }]
  }
}

Delivery: 10-second timeout, any 2xx counts as received. Failures retry after 1 min, 5 min, 30 min, 2 h and 12 h. After 20 consecutive failures the endpoint is paused and shown as such in the panel; press Resume to re-enable. Send test fires a webhook.test event immediately.

4 · Verify a webhook signature

We follow the Standard Webhooks spec, so any library for it works. By hand:

import { createHmac, timingSafeEqual } from "node:crypto";

export function verify(secret, headers, rawBody) {
  const id = headers["webhook-id"], ts = headers["webhook-timestamp"], sig = headers["webhook-signature"];
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;          // 5-minute replay window
  const key = Buffer.from(secret.replace(/^whsec_/, ""), "base64");
  const expected = createHmac("sha256", key).update(`${id}.${ts}.${rawBody}`).digest("base64");
  return sig.split(" ").some((s) => {
    const v = s.replace(/^v1,/, "");
    return v.length === expected.length && timingSafeEqual(Buffer.from(v), Buffer.from(expected));
  });
}

Use the raw request body (before JSON parsing). webhook-id is unique per delivery — use it to de-duplicate retries.

5 · Read received mail & attachments

GET https://allyourinboxes.com/api/v1/emails/receiving?limit=20&unanswered=true&domain=acme.com&q=refund
GET https://allyourinboxes.com/api/v1/emails/receiving/:id                # text + attachment links while retained
GET https://allyourinboxes.com/api/v1/emails/receiving/:id/attachments
GET https://allyourinboxes.com/api/v1/inboxes                             # connected addresses (alias: /domains)
GET https://allyourinboxes.com/api/v1/events?kind=blocked                 # the audit ledger

Retention: by design we delete message bodies once the notification is delivered. When your organization has a webhook or a read key, bodies and attachments are kept for 24 hours after arrival and then removed; text_expires_at tells you when. Metadata (from, subject, dates, answered) stays.

6 · Reply in-thread

The one thing a sending API can't do for you: answer a customer from the address they wrote to, inside the same conversation. We set In-Reply-To/References and send through that inbox's own sending path.

curl https://allyourinboxes.com/api/v1/emails/receiving/cm…/reply \
  -H "Authorization: Bearer ayi_live_…" -H "Content-Type: application/json" \
  -d '{ "text": "Refund issued — you will see it in 3–5 days." }'
# → { "id": "…" }   (reply.sent webhook follows)

Block a sender: POST /inboxes/:id/blocked with { "pattern": "@spammer.com" }.

7 · MCP server for AI agents

Give Claude, Cursor, VS Code or any MCP client a key with the scopes you want the agent to have. Endpoint: https://allyourinboxes.com/mcp (Streamable HTTP, stateless).

{
  "mcpServers": {
    "allyourinboxes": {
      "url": "https://allyourinboxes.com/mcp",
      "headers": { "Authorization": "Bearer ayi_live_…" }
    }
  }
}

Tools: list_inboxes, list_emails (filters: inbox, domain, from, subject, unanswered), get_email (text + attachment links), reply_to_email (in-thread, html and attachments allowed), send_email, block_sender, list_events. A read-only key makes the agent read-only — scopes are enforced per tool, not by the agent's good behaviour.

8 · Limits, errors, retention

  • Rate: 10 requests/second per key (600/min). Over it: 429 rate_limit_exceeded.
  • Monthly API sends: Starter 2,000 · Pro 10,000 · Business 50,000. Free: read-only API, 1 webhook, MCP. Over quota: 429 monthly_quota_exceeded.
  • Attachments: 10 MB per email, in and out.
  • Idempotency-Key: ≤256 chars, remembered 24 h; the same key with a different payload returns 409 invalid_idempotent_request.
  • Where mail actually goes out from: your inbox's own SMTP or Google/Microsoft OAuth — we never send as you from our servers, which is why deliverability follows your domain's SPF/DKIM, not ours. Deliverability guide →

All your email. One place.

Connect any inbox. Send from the right address automatically. Free plan forever, paid from $6.99/mo, and it never touches how your mailboxes are set up.

Try it free