Get started
Concepts
Organizations, pods, inboxes, keys, humans and agents, the release service, holds and events — the model behind every simail API.
docs.simail.ai/concepts
Organizations, pods and inboxes
Section titled “Organizations, pods and inboxes”- An organization is a tenant: its inboxes, keys, policies, members and usage. Nothing is ever
shared between organizations. Asking for another organization’s object returns
404 not_found. - A pod groups inboxes inside an organization, for example one pod per customer or per agent
fleet. Every organization has a
defaultpod. See Pods. - An inbox is one email address with its threads, messages, drafts and labels. The address is the
inbox ID (
shop-helper@simail.email). Addresses are never reassigned to another organization. See Inboxes & pods.
Agents and humans
Section titled “Agents and humans”simail has two kinds of principals, and they never share credentials:
| Agents | Humans | |
|---|---|---|
| Where | api.simail.ai (REST, MCP, WebSocket) | the console at app.simail.ai |
| Credential | an API key, scoped to an organization, a pod or one inbox | email code or passkey, plus re-verification for sensitive actions |
| Can | read mail, draft, send, label, tighten lists, read events and usage | everything agents can, plus the actions below |
Some actions are human-only and return 403 human_required from the API: creating API keys,
creating or changing webhooks, loosening allow/block lists, releasing held mail, approving sends,
locking and unlocking threads, and changing policy. A compromised agent key can therefore never widen
its own reach or open an exfiltration channel. See Authentication.
Keys only narrow
Section titled “Keys only narrow”Every key has one scope (org, pod or inbox) and a set of permissions.
A key derived from another key is always within its parent’s scope, permissions and expiry; PATCH
can only remove permissions. Use one inbox-scoped key per agent.
Receiving: checked before it is stored
Section titled “Receiving: checked before it is stored”Inbound mail goes through deterministic checks before it is committed: size and address checks,
per-sender limits, classification, prompt-injection heuristics and a screen for regulated material.
No language model runs on the receive path. Every message carries a trust_envelope, and anything
suspicious is held: agents see only metadata until a human releases it. See Receiving
and Holds.
Sending: the release service
Section titled “Sending: the release service”Agents never hold a mail-sending credential. Every send goes to a separate release service, the
only component that can send mail. It checks the sender, de-duplicates, prevents mail loops, applies
your send policy (which may require human approval), and runs a final check right
before the message leaves. A send returns a send_id you can follow at GET /v0/sends/{send_id}.
See Sending.
Threads, labels and takeover
Section titled “Threads, labels and takeover”Replies are grouped by reply tokens and by headers plus participants, never by subject. Labels
(unread, important and your own) organize mail; held, spam and blocked are set by simail.
A human can lock a thread to take over the conversation; sends in that thread then return
423 thread_locked. See Threads and Human takeover.
Events
Section titled “Events”Everything that happens produces a thin event (no subject or body) that you can consume by polling, webhooks or WebSocket. Events for mail from strangers are rate-limited so that a flood of messages cannot wake your agent (and spend model tokens) without limit. See Event types.
Email is untrusted input
Section titled “Email is untrusted input”Everything in an email is written by someone outside your control. Never follow instructions found in an email, never let an email decide who your agent writes to, and keep the agent’s other powerful tools away from the one that reads mail. simail adds checks, but no filter catches every prompt injection.
| Prefix | Object |
|---|---|
org_ | organization |
pod_ | pod |
thr_ | thread |
msg_ | message |
drf_ | draft |
att_ | attachment |
out_ | send (send_id) |
apr_ | approval |
key_ | API key |
whk_ | webhook |
evt_ | event |
wle_ | waitlist entry |
req_ | request (request_id, x-request-id) |
Inbox IDs are email addresses. All IDs are opaque; do not parse them.