AgentsJuly 30, 20266 min read

Give Your AI Agent an Email Address in One API Call

Agents can send HTTP anywhere, but half the internet still answers by email: verification codes, receipts, notifications. One keyless call gives an agent a real inbox whose mail becomes webhook events it can read back over the same API.

An AI agent can register for a service, kick off a job, or file a support ticket, and then the flow stops, because the answer arrives somewhere the agent doesn't exist: an email inbox. Verification codes, receipts, "your export is ready" notifications, password resets. Email is the internet's oldest callback mechanism, and agents don't have an address.

This post shows the smallest fix we could build. One API call, no signup, returns a working email address whose incoming mail becomes structured events the agent reads back over HTTP, in the same event log its webhooks land in.

TL;DR

  • POST https://anyhook.net/api/v1/quickstart (no auth) returns an inbox_address like q-cd3fe0f8.quickstart@anyhook.net plus a webhook inbound_url and an API key
  • Mail sent to that address becomes an email.received event: from, to, subject, message_id, and the complete raw MIME message
  • The agent reads it with GET /api/v1/events, or over MCP with anyhook_inbox / anyhook_events / anyhook_inspect (registry: net.anyhook/anyhook, remote endpoint https://anyhook.net/mcp)
  • It receives only. It cannot send or reply, and that's a deliberate boundary, not a roadmap gap
  • Free endpoints expire in 7 days unless claimed; the free tier caps at 100 events/day

The one call

curl -X POST https://anyhook.net/api/v1/quickstart
{
  "inbound_url": "https://in.anyhook.net/q-cd3fe0f8/quickstart",
  "inbox_address": "q-cd3fe0f8.quickstart@anyhook.net",
  "api_key": "ahk_live_…",
  "claim_url": "https://anyhook.net/claim/…",
  "expires_at": "2026-08-06T…"
}

You don't create an account, solve a captcha, or click through an OAuth consent screen. That matters because the caller here is often not a person. It's an agent mid-task, and every signup form in the loop is a place the task dies. The endpoint is ephemeral (7 days) until a human claims it via claim_url, which is also the abuse ceiling: nothing anonymous outlives its TTL.

The same app now answers on two transports:

TransportAddress
HTTP webhookhttps://in.anyhook.net/q-cd3fe0f8/quickstart
Emailq-cd3fe0f8.quickstart@anyhook.net

Both feed one event log, so "wait for the Stripe webhook" and "wait for the confirmation email" are the same operation from the agent's side: poll the events API, inspect the payload.

What an email becomes

Send any mail to the address. Within seconds it shows up as an event:

{
  "type": "email.received",
  "from": "noreply@github.com",
  "to": "q-cd3fe0f8.quickstart@anyhook.net",
  "subject": "Your verification code is 481920",
  "message_id": "<abc123@mail.example.com>",
  "date": "Thu, 30 Jul 2026 11:42:31 +0700",
  "size": 7026,
  "raw": "Received: from …"
}

raw is the complete, unmodified MIME message: every header (including the DKIM and ARC results stamped by the receiving edge), every part, every attachment, exactly as it arrived. The metadata fields are conveniences; the raw message is the source of truth. For the most common agent case, pulling a code out of a verification email, the subject line alone is usually enough. For anything richer, parse the MIME with your language's standard library. That's what it's for.

Reading it back:

curl https://anyhook.net/api/v1/events \
  -H "Authorization: Bearer ahk_live_…"

Over MCP

If the agent speaks MCP, it never touches curl. The server is listed in the official MCP registry as net.anyhook/anyhook, with a remote streamable-HTTP endpoint at https://anyhook.net/mcp:

  1. anyhook_quickstart returns an inbox_address directly
  2. anyhook_inbox returns the address for an existing app, plus its webhook URL
  3. anyhook_events / anyhook_inspect read what arrived

The quickstart tool is the whole onboarding. An agent that discovers the server in a registry can mint itself an inbox and start receiving without a human in the loop. The human enters later, if ever, to claim the account.

How it works (and why the address looks like that)

Under the hood there is deliberately no second pipeline:

  1. A Cloudflare Email Routing catch-all hands every message for the domain to the same edge Worker that receives webhooks
  2. The Worker splits the address's local part on its last dot: {user-slug}.{app-slug}@anyhook.net. Slugs are sanitised to [a-z0-9-] at creation, so they can never contain a dot, which makes the split unambiguous by construction
  3. The message is repackaged as the HTTP request it would have been, and everything downstream (quota, payload limits, queueing, retry, delivery to your destinations, the event log) is the exact same code path webhooks take

Mail that doesn't parse to a real app is rejected at SMTP time, not silently swallowed. A sender who gets no error assumes delivery. Oversized messages bounce the same way.

Two properties carry over from the webhook side for free. Message bodies are AES-256-GCM encrypted before they touch the database. And every event's hash is folded into a per-app chain that gets sealed daily, with each day's root committed to a public git repository that AnyHook holds no credentials for. If we edited a stored email after the fact, the published anchors would stop verifying.

What this is not

It does not send. No replies, no outbound mail, no SMTP credentials. Sending is where deliverability, SPF/DKIM alignment, IP reputation, and spam liability live. That's a different discipline with different failure modes. If your agent needs full two-way conversational email as a product, that category exists (AgentMail raised on exactly that thesis). A receive-only inbox bolted onto a webhook relay is a narrower thing: one event log for everything that comes in.

It is not a burner-mail service. The intended use is mail your own systems generate: confirmations for accounts your agent legitimately operates, notifications from services you integrate, receipts from your own flows. Free endpoints are rate-limited, capped, and expire, and abuse patterns get blocked. If a service's terms prohibit automated signup, an inbox doesn't change that.

It is polling, not push. The agent asks "what arrived?" and nothing wakes it. MCP's current transport model is request/response, so a stateless poll is the honest primitive. When you need lower latency, attach a destination_url and the event is forwarded to your own server the moment it arrives. The email becomes a webhook.

Try it

# 1. mint an inbox (no signup)
curl -X POST https://anyhook.net/api/v1/quickstart

# 2. send any email to the inbox_address you got back

# 3. read it
curl https://anyhook.net/api/v1/events -H "Authorization: Bearer <api_key>"

Total setup time is however long step 2's email takes to arrive.

All postsJuly 30, 2026 · 6 min

Stop losing webhooks.

Change one URL. Get retries, event log, and one-click replay.