← Back to home

API Reference

myagentinbox exposes a small REST API for creating disposable email inboxes, reading messages, and downloading attachments. Everything is JSON over HTTPS. No authentication, no API keys, no SDK required.

Overview

The API has four endpoints — create an inbox, get an inbox, list messages, get a message — plus one for downloading attachments. Inboxes and all their data auto-delete 24 hours after creation. There's also an MCP server at /mcp for AI agents.

Authentication

None. All endpoints are public. Rate limits are enforced per IP address.

Base URL

https://myagentinbox.com

Response format

Every JSON response is wrapped in either a data field (success) or an error field (failure). This shape is stable; clients can rely on it.

// Success
{ "data": { ... } }

// Error
{ "error": { "code": "not_found", "message": "Inbox not found or expired" } }

Attachment downloads are the exception — they return raw binary with appropriate Content-Type and Content-Disposition headers.

Errors

Errors use standard HTTP status codes plus a JSON body with a stable code string.

StatusCodeMeaning
404not_foundInbox or message doesn't exist or has expired.
429rate_limitedYou exceeded the per-IP rate limit. The body carries retry_after (seconds) and higher_limits, and the same value is in the Retry-After header.
500internal_errorServer-side problem. Retries are usually safe.

Rate limits

Limits are scoped per client IP.

BucketLimitScopeApplies to
Inbox creation1 / 300sGlobalPOST /api/inboxes
Inbox creation10 / dayGlobal, resets 00:00 UTCPOST /api/inboxes
Read20 / 60sPer edge locationAll GET /api/inboxes/... endpoints

Creation limits are enforced globally, so they apply no matter which Cloudflare location serves your request. The read limit is evaluated per edge location, which means a client spread across regions may see more headroom than the stated figure — do not depend on that.

Rate-limited responses return 429 with a Retry-After header indicating how long to wait:

{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit reached: 1 inbox per 5 minutes per IP. ...",
    "retry_after": 300,
    "higher_limits": "hello@myagentinbox.com"
  }
}

If you're hitting limits in CI, raise the polling interval and keep email-dependent tests to a nightly job. If you need volume, get in touch — higher limits and a dedicated domain are what we're building next.

Create inbox

Creates a new disposable inbox with a randomly generated address. The inbox lives for 24 hours, then everything tied to it is deleted.

POST/api/inboxes

Request

No body, no headers required.

Example

curl -s -X POST https://myagentinbox.com/api/inboxes
const r = await fetch("https://myagentinbox.com/api/inboxes", {
  method: "POST",
});
const { data } = await r.json();
console.log(data.address);
import httpx

r = httpx.post("https://myagentinbox.com/api/inboxes")
r.raise_for_status()
print(r.json()["data"]["address"])

Response 201 Created

{
  "data": {
    "address": "a7k2m9x4bp@myagentinbox.com",
    "created_at": "2026-04-30T14:22:11.482Z",
    "expires_in": "24h"
  }
}

Get inbox

Returns metadata for an existing inbox. Useful for confirming an address is still alive.

GET/api/inboxes/{address}

Path parameters

NameTypeDescription
addressstringFull inbox address, e.g. a7k2m9x4bp@myagentinbox.com. URL-encode if needed.

Example

curl -s https://myagentinbox.com/api/inboxes/a7k2m9x4bp@myagentinbox.com

Response 200 OK

{
  "data": {
    "address": "a7k2m9x4bp@myagentinbox.com",
    "created_at": "2026-04-30T14:22:11.482Z"
  }
}

Returns 404 not_found if the inbox doesn't exist or has expired.

List messages

Lists all messages currently in an inbox, newest first. Each entry is a summary — use Get message for full content.

GET/api/inboxes/{address}/messages

Example

curl -s https://myagentinbox.com/api/inboxes/a7k2m9x4bp@myagentinbox.com/messages

Response 200 OK

{
  "data": [
    {
      "id": "01HZX9...",
      "from": "noreply@example.com",
      "subject": "Verify your email",
      "preview": "Your verification code is 482913. This code expires in...",
      "received_at": "2026-04-30T14:22:48.103Z",
      "has_attachments": false
    }
  ]
}

Returns 404 if the inbox doesn't exist. Returns data: [] if the inbox exists but has no messages yet.

Get message

Returns the full content of a single message: text and HTML bodies, recipient list, attachment metadata.

GET/api/inboxes/{address}/messages/{id}

Path parameters

NameTypeDescription
addressstringFull inbox address.
idstringMessage ID returned by List messages.

Response 200 OK

{
  "data": {
    "id": "01HZX9...",
    "from": "noreply@example.com",
    "to": ["a7k2m9x4bp@myagentinbox.com"],
    "subject": "Verify your email",
    "text": "Your verification code is 482913.\n\nThis code expires in 10 minutes.",
    "html": "<p>Your verification code is <b>482913</b>.</p>...",
    "attachments": [
      {
        "filename": "receipt.pdf",
        "content_type": "application/pdf",
        "size": 14823,
        "r2_key": "a7k2m9x4bp@myagentinbox.com/01HZX9.../receipt.pdf"
      }
    ],
    "received_at": "2026-04-30T14:22:48.103Z"
  }
}

Download attachment

Returns the raw bytes of one attachment. The response sets Content-Type from the original email and Content-Disposition: attachment; filename="...".

GET/api/inboxes/{address}/messages/{id}/attachments/{filename}

Example

curl -s -o receipt.pdf \
  https://myagentinbox.com/api/inboxes/a7k2m9x4bp@myagentinbox.com/messages/01HZX9.../attachments/receipt.pdf

Returns 404 if the inbox, message, or attachment doesn't exist.

MCP server

For AI agents, the same operations are exposed as a Model Context Protocol server over Streamable HTTP.

ALL/mcp

Connect

{
  "mcpServers": {
    "myagentinbox": {
      "command": "npx",
      "args": ["mcp-remote", "https://myagentinbox.com/mcp"]
    }
  }
}

Framework-specific guides: Claude, Cursor, OpenAI Agents SDK, LangChain, Vercel AI SDK.

MCP tools

ToolArgsReturns
create_inboxNew address with 24 h TTL.
check_inboxaddressArray of message summaries.
read_messageaddress, message_idFull message.
download_attachmentaddress, message_id, filenameImage as base64, text inline, binary as download URL.

Object types

Inbox

FieldTypeDescription
addressstringFull email address, e.g. a7k2m9x4bp@myagentinbox.com.
created_atstring (ISO 8601)UTC timestamp the inbox was created.
expires_instringHuman-readable TTL, e.g. "24h". Only on the create response.

MessageSummary

FieldTypeDescription
idstringMessage ID. Pass to Get message.
fromstringSender address.
subjectstringSubject line.
previewstringFirst 200 characters of the plain-text body.
received_atstring (ISO 8601)UTC timestamp the message was received.
has_attachmentsbooleanTrue if the message has at least one attachment.

Message

FieldTypeDescription
idstringMessage ID.
fromstringSender address.
tostring[]Recipient addresses (the inbox plus any cc'd addresses on this domain).
subjectstringSubject line.
textstringPlain-text body, MIME-decoded.
htmlstringHTML body, MIME-decoded.
attachmentsAttachment[]Attachment metadata.
received_atstring (ISO 8601)UTC timestamp.

Attachment

FieldTypeDescription
filenamestringOriginal filename.
content_typestringMIME type from the email.
sizenumberSize in bytes.
r2_keystringInternal storage key. You can ignore this; use the download endpoint to fetch bytes.

Expiry behavior

One subtle behavior worth knowing about:

The practical implication: if a test is going to wait on an email near the inbox's expiry, create a fresh inbox first.


Spotted something wrong or missing? Email hello@myagentinbox.com.