Email infrastructure for AI agents
One API call gives your agent a real inbox. It receives mail, replies in the same thread, and calls your code the moment something arrives. Open source, self-hostable, webhooks on every plan.
threadreplied
linkpdf
otp 482913
link
thread
otp 771204
From SMTP to your agent in one call
Create an inbox, wait for mail, reply in the thread. send0 handles the parts of email nobody wants to build.
const inbox = await send0.inboxes.create({ name: "signup-agent", }); inbox.address // "signup-agent@send0.email"
const msg = await send0.inboxes.wait(inbox.id, { from: "*@github.com", timeout: 60, }); msg.extracted.otp // "482913" msg.extracted.action_link // "https://github.com/…"
await send0.messages.reply(msg.id, { text: "Thursday at 3 works.", }); // In-Reply-To and References set, // subject kept: same thread everywhere
POST https://you.dev/hooks
send0-signature: t=1760000000,v1=5f3a…
{ "type": "message.received",
"data": { "id": "msg_8f2k", "thread_id": "thr_3Lp8" } }One API, four ways in
TypeScript and Python SDKs, an MCP server for Claude and Cursor, tools for the Vercel AI SDK and LangChain, or plain HTTP.
import { Send0 } from "@send0/sdk"; const send0 = new Send0(); // reads SEND0_API_KEY const inbox = await send0.inboxes.create({ name: "signup-agent" }); const msg = await send0.inboxes.wait(inbox.id, { from: "*@github.com" }); console.log(msg.extracted.otp); // "482913" await send0.messages.reply(msg.id, { text: "Thanks, confirmed." });
from send0 import Send0 send0 = Send0() # reads SEND0_API_KEY inbox = send0.inboxes.create(name="signup-agent") msg = send0.inboxes.wait(inbox.id, from_="*@github.com") print(msg.extracted.otp) # "482913" send0.messages.reply(msg.id, text="Thanks, confirmed.")
# Claude Code, Cursor, any MCP client claude mcp add send0 --env SEND0_API_KEY=s0_live_… \ -- npx -y @send0/mcp # tools create_inbox · wait_for_email · reply · send_email search_messages · get_thread · list_threads
Built so agents can't become spammers
- sender checks
- spf · dkim · dmarcVerdicts on every inbound message.
- untrusted input
- injection flagPrompt-injection signals on every email.
- free tier
- reply-onlyOnly people who wrote first can be emailed.
- new accounts
- 50 / dayRises with a clean sending record.
- auto-pause
- 0.3% · 5%Complaints or hard bounces stop sending.
- scoped keys
- per inboxGive an agent access to one inbox only.
Run the whole thing on your own servers
The same code runs our cloud. Docker Compose on any server with port 25, or one Cloudflare Worker with a deploy button.
$ for f in compose.yml Caddyfile .env.example; do curl -fsSLO "…/send0-v2/v0.2.0/selfhost/$f"; done $ cp .env.example .env # your domains and mail relay $ docker compose up -d ✓ postgres · send0 api + dashboard · smtp :25 · caddy
Free to run yourself
Self-host
- The full server, AGPL-3.0
- Same API, SDKs and MCP
- Pay only for a server and mail relay
send0 Cloud
- Addresses on send0.email
- A reply-only free tier
- Webhooks included
How is it different from a transactional email API?
Those are built to send receipts; receiving is an add-on that forwards raw mail. send0 starts from the inbox: messages are parsed, threaded and checked, codes are extracted, and your agent replies in the same thread.
Will sites block send0.email addresses as disposable?
We work to make sure they don't. Every send0.email inbox belongs to a verified account, and we never market it as throwaway mail. Need your own domain? Self-host today; custom domains are coming to paid cloud plans.
How do you keep agents safe from malicious email?
Every message carries SPF, DKIM and DMARC results and a prompt-injection flag. The MCP server hands bodies to the model as untrusted data. Approval mode puts a person before every send, and keys can be limited to one inbox.
What does AGPL-3.0 mean for me?
Calling the API puts no obligations on your code, and you can self-host commercially. Change the server and offer it to others over a network, and you share those changes. The SDKs and MCP server are MIT.