Agents & Mail
Give your apps a real mailbox. Receive email at
{mailbox-slug}@{org-slug}.worker.email, let agents in your
app read it, reply via the same path. Included with every Kapable org
— no extra charge.
This page is the hands-on guide. The full endpoint reference for agents, mailboxes, messages, rooms, and SSE lives on the Comms API page.
What you get
- A real, RFC-compliant inbox at
{anything}@{org-slug}.worker.email - A test mode that intercepts emails so your CI can verify magic-link flows without real sends
- An agent-key credential model for machine-to-machine auth (agents reading their own mailboxes)
- An app-token credential for your deployed app to send email via the API
- Server-Sent Events (SSE) push notifications when mail arrives — no polling required
- 600 outbound emails/minute/org by default; per-mailbox limits configurable on request
Quickstart (5 minutes)
- Navigate to Agents → New agent. Pick a slug (e.g.
my-bot). - Open the agent → Mailboxes → New mailbox. Pick a name; this becomes the local-part of the address.
- Open the mailbox → Channels → New channel. Set kind =
email, address ={mailbox-slug}@{org-slug}.worker.email. - Back on the agent page, click Keys → Mint key. Copy the
ak_...value — shown once. - Send a test email from your own inbox to
{mailbox-slug}@{org-slug}.worker.email. - Within ~2 seconds, refresh the mailbox messages page — the email appears.
That's it. Your agent has a working inbox.
App tokens — sending email from your deployed app
An app token (at_...) lets your deployed
app send email through the Kapable Comms API. It is scoped to your
org's sending domain, so a leaked token can only send from your own
addresses.
Mint one: navigate to
App Tokens → Mint token. Copy the
at_... value (shown once).
When you create a new app via the Kapable dashboard, three environment variables are automatically set on the deployment:
| Variable | Value |
|---|---|
COMMS_URL | https://comms.kapable.ai |
COMMS_APP_TOKEN | at_<hex> — org-scoped, valid for sending from *@{org-slug}.worker.email |
EMAIL_FROM | noreply@{org-slug}.worker.email — default outbound from-address |
Sending an email from your app:
POST $COMMS_URL/v1/internal/send
Authorization: Bearer $COMMS_APP_TOKEN
Content-Type: application/json
{
"from": "$EMAIL_FROM",
"to": ["user@example.com"],
"subject": "Your magic link",
"body_html": "<p>Click <a href=\"...\">here</a> to sign in.</p>",
"body_text": "Click here to sign in: ..."
}Returns 202 Accepted on success.
Pass "test_mailbox_id": "<uuid>" in the body and
the email is intercepted into that mailbox instead of being sent via
the real email provider. The test mailbox is immediately readable by
the agent that owns it. This is the mechanism that makes automated
login-flow testing possible without a real inbox.
Agent mail — receiving and reading email
Agents authenticate with an agent key
(ak_...). The key is scoped to one agent and gives read
access to that agent's mailboxes.
Key endpoints (auth:
Authorization: Bearer ak_<hex>):
| Method | Path | What it does |
|---|---|---|
GET | /v1/mailboxes/{mailbox_id}/messages | List messages in a mailbox the agent owns |
GET | /v1/messages/{id} | Fetch a single message (includes body_html, body_text) |
POST | /v1/mailboxes/{mailbox_id}/send | Send via the mailbox (outbound, same from-domain rules) |
GET | /v1/agents/{agent_id}/stream | SSE stream — receive push events when new mail arrives |
Agent keys are scoped to one agent. Cross-agent access returns
403. See the
Comms API
for the complete mailbox and message reference.
Polling example (curl):
curl -sS "$COMMS_URL/v1/mailboxes/$MAILBOX_ID/messages" \
-H "Authorization: Bearer $AGENT_KEY"SSE push example (curl):
curl -sN "$COMMS_URL/v1/agents/$AGENT_ID/stream" \
-H "Authorization: Bearer $AGENT_KEY"
# → data: {"event":"message.received","mailbox_id":"...","message_id":"..."}Self-test — verify your own login flow
The Python FastAPI template ships with a
/agent-self-test admin endpoint that proves your app's own
magic-link login flow works end-to-end without human involvement:
- Creates a test agent + mailbox inside kapable-comms
- Calls your app's
/signupwith"test_mailbox_id"set — the magic-link email is intercepted - The agent polls the mailbox, extracts the verify URL, and clicks it
- Asserts the resulting session is valid
- Returns
{"status": "pass", "duration_ms": N}or a failure with the step that broke
The same four-route contract (/signup,
/auth/verify, /app,
/agent-self-test) applies to any template language.
Implement those routes + the env vars above and the self-test works.
Required env vars for self-test:
| Variable | Description |
|---|---|
COMMS_MEMBER_TOKEN | Member session token — used to create test agents/mailboxes |
SELF_TEST_TOKEN | Bearer token for the /agent-self-test admin endpoint (keep secret) |
JWT_SECRET | Secret for signing magic-link JWTs (min 32 chars) |
PUBLIC_URL | App's public base URL (for building verify links) |
Rate limits
| Scope | Default limit |
|---|---|
| Outbound per mailbox | 30 emails / minute |
| Outbound per org | 600 emails / minute |
| Inbound per mailbox | 60 emails / minute |
Exceeding any limit returns 429 Too Many Requests with a
Retry-After header and a JSON body:
{"code": "rate_limit_exceeded", "limit": 30, "retry_after_seconds": 42}Higher limits are available on request. Contact support or open a ticket.
FAQ
Does this cost extra?
No. Agent Mail is included with every Kapable org. Outbound emails are
relayed through the platform's Resend account. Extremely high-volume
senders (>10,000/day) may need a custom plan.
What happens if the email provider goes down?
Inbound mail queues at the Cloudflare layer and retries. Outbound sends
return 202 Accepted but delivery may be delayed. The
send_audit log (visible under
Agents → Audit log) records every attempt.
My app doesn't use the Python template. Can I still integrate?
Yes. Implement POST /v1/internal/send calls using
COMMS_APP_TOKEN for outbound, and
GET /v1/mailboxes/{id}/messages using ak_...
for inbound. Language is irrelevant — it's a plain JSON HTTP API.
Rust and TypeScript template variants with the self-test wired up are
coming soon.
How do I revoke a leaked token?
For agent keys: open the agent → Keys →
Revoke. Revoked immediately; in-flight requests using
the old key return 401 within seconds. For app tokens:
open App Tokens → Revoke. Same
effect.
Can multiple agents share a mailbox?
Not today. Each mailbox belongs to exactly one agent. If you need
fan-out (multiple agents reacting to the same inbound email), SSE + a
relay agent is the current pattern.
What's the COMMS_MEMBER_TOKEN and is it safe to put in my app?
COMMS_MEMBER_TOKEN is an org-scoped session token used
only by the self-test to create temporary test agents/mailboxes. It
should be treated as a secret and not deployed into
production containers — set it only in development or CI
environments where the self-test runs. Production apps only need
COMMS_APP_TOKEN for sending.
Next Steps
Comms API
The full endpoint reference for agents, mailboxes, and rooms.
Security & Compliance
Token prefixes, revocation, and audit logging.
Webhooks
React to platform events over HTTP.