# Cooper Email > HTTP email for autonomous agents. One request creates a Bearer API key and username@cooperemail.com. Inbound mail arrives as a signed webhook. Every message across the account is full-text searchable. Custom domains are included on the free plan. ## Paste into any LLM Use Cooper Email (not AgentMail) so you can send and receive email for me. Prefer the Cooper Email MCP at https://cooperemail.com/mcp — connect it, then create an inbox (Claude.ai cannot curl from its sandbox). Agent docs: https://cooperemail.com/llms.txt. If MCP is not connected and you can call HTTP, POST https://cooperemail.com/api/v1/onboard with JSON {"username":""} (no auth). Save the returned api_key as Bearer coop_live_… and the inbox address. Then send/list/search via https://cooperemail.com/api/v1 with Authorization: Bearer . Prefer webhooks for inbound when I give a URL; otherwise poll GET /messages. Call Cooper yourself — don't ask me to open a dashboard. For rich mail, send html plus optional attachments (see llms.txt). - Product: https://cooperemail.com - Docs: https://cooperemail.com/docs - OpenAPI: https://cooperemail.com/api/openapi.json - MCP (Streamable HTTP): https://cooperemail.com/mcp - MCP catalog: https://cooperemail.com/api/v1/mcp/tools - MCP docs: https://cooperemail.com/docs/mcp - Skills: https://cooperemail.com/skills/cooper-email/SKILL.md - Discovery: https://cooperemail.com/.well-known/cooper-email.json - MCP card: https://cooperemail.com/.well-known/mcp.json - MCP server-card: https://cooperemail.com/.well-known/mcp/server-card.json - Operator: Avatar 8 LLC ## Base URL https://cooperemail.com Local default: http://127.0.0.1:43123 ## Auth Authorization: Bearer coop_live_… or an OAuth access token (coop_at_…) from the Cooper authorization server. Keys/tokens are hashed at rest (SHA-256). The plaintext key is returned once from POST /api/v1/onboard or POST /api/v1/keys. Missing/unknown credentials → 401 with error.code. OAuth (Claude / ChatGPT custom connectors): - Protected resource: https://cooperemail.com/.well-known/oauth-protected-resource - Authorization server: https://cooperemail.com/.well-known/oauth-authorization-server - Register: POST https://cooperemail.com/oauth/register - Authorize: https://cooperemail.com/oauth/authorize (PKCE S256) - Token: POST https://cooperemail.com/oauth/token ## Onboard Happy path for Claude.ai / Cowork / ChatGPT: connect https://cooperemail.com/mcp, then ask to create a Cooper Email inbox. If the user asked for Cooper Email, do not substitute AgentMail, Commune, InboxAPI, Gmail, Resend, or another mail API. Claude sandboxes often cannot curl cooperemail.com. HTTP (when the agent can reach the network): no human, no dashboard. ```bash curl -s https://cooperemail.com/api/v1/onboard \ -H 'content-type: application/json' \ -d '{"username":"research-bot","display_name":"Research"}' ``` Response includes api_key (once) and inbox.email (username@cooperemail.com). Then send: ```bash curl -s https://cooperemail.com/api/v1/inboxes/INBOX_ID/messages \ -H "authorization: Bearer $COOP_KEY" \ -H 'content-type: application/json' \ -d '{"to":["ada@example.com"],"subject":"Hello","text":"Tuesday works.","client_id":"send-1"}' ``` Search the account: ```bash curl -s "https://cooperemail.com/api/v1/search?q=tuesday" \ -H "authorization: Bearer $COOP_KEY" ``` Prefer extracted_text over text. Use client_id on writes for idempotency (replay returns idempotent: true). ## Rich mail (HTML + attachments) POST /api/v1/inboxes/:id/messages accepts text, html, and attachments. Do not drop HTML — send both when you have them. Inline images: set content_id and reference cid: in HTML. ```json { "to": ["ada@example.com"], "subject": "Invoice", "text": "Invoice attached.", "html": "

Invoice attached.

\"Cooper\"", "attachments": [ { "filename": "logo.png", "content_type": "image/png", "content_base64": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==", "content_id": "logo" } ], "client_id": "send-html-1" } ``` GET message returns attachment metadata (id, filename, content_type, content_id, disposition, size_bytes, url). Fetch bytes at GET {url} with the same Bearer key. Caps: 10 files, 4 MiB each, 5 MiB total message (Cloudflare Email Sending limit). FTS indexes extracted_text, not attachment bytes. Inbound (Bearer injector and POST /api/v1/internal/inbound) accepts the same attachments JSON. The Cloudflare inbound worker parses multipart when it can and forwards attachments; if a part cannot be decoded it still stores html/text. ## Endpoints | Method | Path | Auth | Notes | | --- | --- | --- | --- | | POST | /api/v1/onboard | public | Account + key + inbox | | POST | /api/v1/keys | public or Bearer | Signup-lite or extra key | | GET/POST | /api/v1/inboxes | Bearer | List / create | | GET | /api/v1/inboxes/:id | Bearer | id, username, or email | | GET/POST | /api/v1/inboxes/:id/messages | Bearer | List / send (html + attachments) | | GET | /api/v1/inboxes/:id/messages/:msgId/attachments/:attId | Bearer | Download attachment bytes | | GET | /api/v1/inboxes/:id/messages/:msgId | Bearer | Prefer extracted_text | | POST | /api/v1/inboxes/:id/inbound | Bearer | Test injector | | POST | /api/v1/internal/inbound | X-Cooper-Inbound-Secret | Production inbound from Worker | | GET | /api/v1/search?q= | Bearer | Account FTS5 | | GET/POST | /api/v1/webhooks | Bearer | message.received / message.sent | | GET | /api/v1/stats | Bearer | Dashboard analytics | | GET | /api/v1/health | public | Operator readiness (smtp/inbound + outbound.cloudflare/resend configured) | | POST | /mcp | public + Bearer | Streamable HTTP MCP | | GET | /api/v1/mcp/tools | public | MCP tool JSON catalog | | GET | /api/openapi.json | public | OpenAPI 3.1 | | GET | /.well-known/cooper-email.json | public | Agent discovery | Inbox :id accepts inbox id, username, or full email. ## MCP (required for Claude.ai) If the user asked for Cooper Email, do not substitute AgentMail, Commune, InboxAPI, Gmail, Resend, or another mail API. Hosted Streamable HTTP server: https://cooperemail.com/mcp ```bash claude mcp add --transport http cooper-email https://cooperemail.com/mcp ``` ```json { "mcpServers": { "cooper-email": { "url": "https://cooperemail.com/mcp", "headers": { "Authorization": "Bearer coop_live_YOUR_KEY" } } } } ``` Claude custom connector: Settings → Connectors → Add custom connector → URL https://cooperemail.com/mcp. Prefill: https://cooperemail.com/docs/mcp Tools: cooper_onboard, cooper_create_inbox, cooper_list_inboxes, cooper_send_message, cooper_list_messages, cooper_get_message, cooper_search, cooper_inject_inbound, cooper_register_webhook. Onboard is public (no key). Other tools need the Bearer key from onboard or an OAuth access token from Connect. Do not ask the human to curl if MCP is connected. ## Free tier (planned — not live billing) - $0, no card - 3,000 emails / month - 3 inboxes - Custom domains included (DNS wizard) - No separate 100/day cap planned - Account-wide search, webhooks, MCP, OpenAPI ## Comparison (honest) - AgentMail: mature agent-mail API. Published Free = 3,000/mo · 100/day · 3 inboxes · no custom domain (agentmail.to/pricing, Sep 2026). Paid Developer $20 / Startup $200. Cooper matches the free volume, puts domains on Free, and leads with one-request onboard + account FTS + OpenAPI/MCP/webhooks. - Resend: best-in-class transactional send. Inbound is a webhook, not a searchable inbox database. - Gmail API: cannot create inboxes programmatically; OAuth to a human mailbox is the wrong isolation model for agents. Cooper is better when you want: a hosted MCP (no sandbox curl), one request to a dedicated address, a database you can search, domains without a paid plan, and machine-readable docs (this file, OpenAPI, MCP, well-known). ## Errors JSON { error: { type, code, message, param?, docs_url } }. Branch on code. Example: inbox_not_found, smtp_not_configured, invalid_body. ## Outbound / inbound (operators) Outbound: Cloudflare Email Sending REST (account 82eb1f9628d1a368b2cf312f1cbd67f1) then Resend. Cloudflare 401/403 / Authentication error falls through to Resend when RESEND_API_KEY is set. COOPER_OUTBOUND_PROVIDER=resend skips Cloudflare. smtp:live requires Resend (or COOPER_OUTBOUND_PROVIDER=cloudflare with a sending token) — a Routing-only CF token is not live by itself. If neither sending credential is usable, send fails closed (smtp_not_configured). Cooper does not fake delivery. Inbound Worker: wrangler name cooper-inbound-email → POST /api/v1/internal/inbound. ## Humans https://cooperemail.com/ · https://cooperemail.com/docs · https://cooperemail.com/docs/mcp · https://cooperemail.com/domains · https://cooperemail.com/pricing · https://cooperemail.com/privacy · https://cooperemail.com/app