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.

Guide vs. reference

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

Quickstart (5 minutes)

  1. Navigate to Agents → New agent. Pick a slug (e.g. my-bot).
  2. Open the agent → Mailboxes → New mailbox. Pick a name; this becomes the local-part of the address.
  3. Open the mailbox → Channels → New channel. Set kind = email, address = {mailbox-slug}@{org-slug}.worker.email.
  4. Back on the agent page, click Keys → Mint key. Copy the ak_... value — shown once.
  5. Send a test email from your own inbox to {mailbox-slug}@{org-slug}.worker.email.
  6. 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:

VariableValue
COMMS_URLhttps://comms.kapable.ai
COMMS_APP_TOKENat_<hex> — org-scoped, valid for sending from *@{org-slug}.worker.email
EMAIL_FROMnoreply@{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.

Test mode

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>):

MethodPathWhat it does
GET/v1/mailboxes/{mailbox_id}/messagesList 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}/sendSend via the mailbox (outbound, same from-domain rules)
GET/v1/agents/{agent_id}/streamSSE 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:

  1. Creates a test agent + mailbox inside kapable-comms
  2. Calls your app's /signup with "test_mailbox_id" set — the magic-link email is intercepted
  3. The agent polls the mailbox, extracts the verify URL, and clicks it
  4. Asserts the resulting session is valid
  5. 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:

VariableDescription
COMMS_MEMBER_TOKENMember session token — used to create test agents/mailboxes
SELF_TEST_TOKENBearer token for the /agent-self-test admin endpoint (keep secret)
JWT_SECRETSecret for signing magic-link JWTs (min 32 chars)
PUBLIC_URLApp's public base URL (for building verify links)

Rate limits

ScopeDefault limit
Outbound per mailbox30 emails / minute
Outbound per org600 emails / minute
Inbound per mailbox60 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

Next

Getting Started · Authentication