AgentAddress v0.2
Give asynchronous work
somewhere to return.
AgentAddress creates a scoped identity with two sides: a public ingress for responses and a bearer-protected queue for the agent that will resume the work.
01 Create a return address
No account or API key is required for MVP provisioning. The response includes a read token exactly once, so persist it with the task state.
curl -X POST https://agentaddress.dev/api/v1/addresses \
-H 'content-type: application/json' \
-d '{"name":"flight quote","task_id":"task_7f2"}'{
"address": {
"id": "addr_8c09…",
"email": "amber-river-71a9d2@inbox.example.com"
},
"credentials": { "read_token": "aa_read_…" },
"endpoints": {
"inbox_url": "https://…/api/v1/inbox/addr_…/aa_ingress_…",
"events_url": "https://…/api/v1/addresses/addr_…/events"
}
}02 Deliver an event
Any system can POST structured JSON to the generated inbox URL. Use an idempotency key when a sender may retry.
curl -X POST "$INBOX_URL" \
-H 'content-type: application/json' \
-H 'idempotency-key: vendor-reply-123' \
-d '{
"type": "quote.ready",
"source": "travel_vendor",
"data": {"total": 4200, "currency": "USD"}
}'A first delivery returns 202 Accepted. Reusing the same idempotency key returns the original event with duplicate: true.
03 Poll and resume
Events are ordered by a monotonically increasing sequence. Pass the last next_cursor as after. Set wait up to 25 seconds for long polling.
curl "$EVENTS_URL?after=0&wait=25" \
-H "authorization: Bearer $READ_TOKEN"After handling an event, acknowledge it with POST /api/v1/addresses/:addressId/events/:eventId/ack and the same bearer token.
To inspect recent history, GET .../events?before=9007199254740991&limit=100 returns the newest events first. Use its next_cursor as the next before value to load older events. The human-readable inbox viewer does this for you.
Inbound email
Every address has an email identity under INBOX_DOMAIN. Resend sends verified email.received webhooks to the service. It routes using the provider's received_for envelope when present, so Bcc and forwarded mail can reach the correct address, then queues message content and attachment metadata. New events carry a server-assigned ingress_surface; resend identifies a verified provider webhook. Treat sender, subject, body, selected mail headers, and attachments as untrusted data.
Resend webhook URL
https://agentaddress.dev/api/v1/email/resend
Events
email.receivedFor an attachment listed in a verified email event, call GET /api/v1/addresses/:addressId/events/:eventId/attachments/:attachmentId with the address read token. The response downloads the bytes from Resend on demand, up to 10 MB. AgentAddress does not store attachment files. The provider can stop retaining an attachment before the queued event expires; in that case the API returns 502 attachment_unavailable. Downloads share the address polling limit. The inbox viewer offers the same download action.
If Resend exhausted webhook retries before an email reached the queue, an owner who has its provider email ID can call POST /api/v1/addresses/:addressId/email/replay with {"email_id":"..."} and the read token. AgentAddress fetches the message, verifies that Resend delivered it to this address, and queues it idempotently. The CLI helper offers replay TASK EMAIL_ID without exposing the read token. Replay depends on provider retention and available inbox capacity; it does not scan all provider mail automatically.
RESEND_API_KEY, RESEND_WEBHOOK_SECRET, and INBOX_DOMAIN in Render. The webhook signing secret is created when you add the webhook in Resend.MCP
Connect an MCP client to https://agentaddress.dev/api/mcp. The stateless server exposes create_return_address, poll_events, and acknowledge_event. It supports the 2026-07-28 protocol and initialization compatibility with 2025 revisions.
{
"mcpServers": {
"agentaddress": {
"url": "https://agentaddress.dev/api/mcp"
}
}
}Queue semantics
At-least-once. Senders should use idempotency keys and consumers should tolerate retries.
Stable sequence ordering within one address. No ordering guarantee across addresses.
Events are retained for 30 days. Addresses have no expiry unless explicitly requested, from 60 seconds to one year.
Tokens are generated with secure randomness and stored only as SHA-256 hashes.
Durable JSON state
Keep task context behind the same private read token. Values last until replaced, deleted, or the address expires or is deleted. State has 32 keys and a 65,536-byte total limit, including keys and metadata; it does not expire with the event history.
node scripts/agentaddress.mjs state-set my-task progress progress.json 0
node scripts/agentaddress.mjs state-get my-task progress
node scripts/agentaddress.mjs state-keys my-taskGET /api/v1/addresses/{id}/state lists keys; GET, PUT and DELETE .../state/{key} operate on a value. PUT accepts {"value":{"step":"waiting"},"if_revision":0}. Omit if_revision to replace, or supply the current revision to avoid overwriting another run. DELETE accepts a numeric If-Match revision. All require the read token; low-level clients handle that credential directly.
Mutations append state.updated or state.deleted to the feed atomically; a full feed prevents the mutation. A stale revision returns 409 revision_conflict. Treat values as untrusted task data and keep credentials in the CLI's private storage.
Send email and reply
Send plain text to one verified contact. The operator must configure OUTBOUND_FROM on a Resend-verified sending domain. That is the sender; Reply-To is this task's inbound email address. Read-token authentication is required, and no agent account is needed.
node scripts/agentaddress.mjs contacts my-task
node scripts/agentaddress.mjs contact my-task person@example.com
node scripts/agentaddress.mjs contact my-task person@example.com SIX_DIGIT_CODE
node scripts/agentaddress.mjs send my-task message.json task-update-1Request verification only with authorization to contact the recipient. The recipient supplies the emailed six-digit code; the API never returns it. Codes expire after 15 minutes and allow five failed attempts. Each address permits 10 contacts. Verification is limited to 5/IP/hour, 3/recipient/UTC day, and 3/address/hour.
GET .../email/contacts reports availability and contacts. POST the same route with email to request a code, or email and code to verify. POST .../email/send accepts to, subject and text, plus a stable Idempotency-Key. Replies also include reply_to_event_id, a retained provider-verified email, and must target its sender or sole Reply-To.
Subject: 200 characters without newlines. Text: 10,000 UTF-8 bytes. Sending permits 20 reservations/address/UTC day, within a shared service budget of at most 100/day including verification emails. New sends reserve two event slots. Reuse the same key and body after failures; changed content returns 409 idempotency_conflict. Keys are retained for at least 24 hours.
Pending sends survive restarts. Provider retries reuse the same idempotency key within 23 hours; later uncertainty produces email.send_uncertain rather than another send. Provider acceptance produces email.sent and does not establish delivery. Standard reply headers preserve context; full threads, search, drafts, scheduled sending and outbound attachments are not implemented.
Limits & recovery
- 20 address creation attempts per IP per minute.
- 30 authenticated polls per address per minute, shared across REST and MCP. Prefer
wait=25on REST when waiting for new events. - 1,000 retained events per address across HTTP and email. Events expire after 30 days; reading and acknowledging do not free capacity.
- 1 MB (1,000,000 bytes) maximum request body and normalized event input.
Rate windows reset on UTC minute boundaries. HTTP 429 rate_limited includes Retry-After and retry_after_seconds. Wait that many seconds before retrying. Successful creation and polling responses include limit, remaining, and reset headers.
A full inbox returns 409 quota_exceeded for new deliveries and preserves existing events. Retried events with the same idempotency key still succeed. Oversized payloads return 413 payload_too_large. MCP reports temporary tool limits with isError, a structured error, and Retry-After.
Resend retries failed deliveries for a finite period. Verified webhook IDs are saved before content fetch. Automatic server maintenance performs bounded provider sweeps and retries pending receipts every five minutes while the server runs. MongoDB leases coordinate instances, and backfill verifies the provider delivery envelope. Recovery still depends on provider retention and available inbox capacity. No new event is reported as accepted unless it was stored.
These limits do not shorten an address's lifetime. AgentAddress is free today. A $17/month paid plan is coming; allowances and launch date are not finalized. See pricing.