Agents
An agent acts for your organization with its own identity — never your login. It can only do what you grant it, and everything it does is recorded against its name. This page covers the three places an agent can run, how an outside agent connects, and the one case where you still need a mailbox API key.
On This Page
Where an agent runs
Every agent is the same underneath — the same powers, the same approval rules, the same record of what it did. What differs is whose hardware it runs on, and that decides how it connects.
AnnexOrbis Cloud
Runs on a model we host. Nothing to install and no key to hand out — create it and grant it powers.
Outsourced
Runs on someone else's servers — your own box, or a hosted assistant. It reaches Annex Orbis over HTTP with one API key.
AnnexOrbis Local
Runs on a machine you authorize, paired with a one-time connect code. Not available to create yet.
Connecting an outsourced agent
Sign in as an owner or admin, open Organization → Agents, and create an agent with the host set to Outsourced. Grant it powers on its Powers tab, then open Connection and create its API key.
One key, shown once
The key looks like clo_agt_…. It identifies this agent, and the agent already belongs to your organization — so there is nothing else to configure. We store only a digest, which means the key cannot be shown to you again: copy it when it appears, and rotate if it is lost.
Give the key to the outside agent and point it at two endpoints. The first tells it what it may do; the second does it.
# What am I allowed to do?
curl https://agent-runtime.annexorbis.com/v1/outsourced/capabilities \
-H "Authorization: Bearer clo_agt_..."
# Do one of them
curl -X POST https://agent-runtime.annexorbis.com/v1/outsourced/capabilities/invoke \
-H "Authorization: Bearer clo_agt_..." \
-H "content-type: application/json" \
-d '{"capability":"crm_contact_create","dry_run":false,"arguments":{ }}'The first call is worth making before anything else: it returns each power the agent holds, the arguments that power takes, whether it needs a human approval, and whether anything is missing — so the agent never has to guess.
Powers: what an agent may do
A capability is something the platform can do — send an email, create a contact, place a call. A power is a capability you have granted to a particular agent. Nothing is on by default: a new agent has no powers until you give it some.
Some powers also need a resource before they work — which mailbox, which phone number, which SMS number. A power granted without one is reported as unusable rather than failing later, so you find out when you grant it and not when the agent tries.
An agent can always ask what it holds, and the answer comes from the same place the rules are enforced — so what it is told and what it is allowed can never drift apart.
Rehearsals and approvals
Two things stand between an agent and the outside world, and both are on by default.
Calls rehearse by default
Every call is a rehearsal unless it explicitly sends "dry_run": false. An agent exploring what it can do changes nothing.
A person approves anything outbound
At Ask first, mail, SMS and calls come back 202 requires_approval with an approval id, and wait. Reading and internal work run normally.
How far an agent gets without a person is its autonomy, set on the Connection tab. There are three levels, and an agent can always read its own from /v1/outsourced/capabilities.
Read only
It can look at anything it has been granted and change nothing. A write is refused outright with 403 — approving will not help, because the refusal is the level itself, not a pending decision.
Ask first
It changes things inside the organization on its own. Anything that leaves — mail, SMS, a call — returns 202 with an approval id and waits for a person. This is the default.
Full autonomy
Nothing waits. Its granted powers and resource bindings still apply; the level never widens them.
The two refusals mean different things and an agent should treat them differently. A 202 is not an error — the work is queued for a human, so wait and re-send with the approval id rather than retrying. A 403 at Read only will never succeed no matter how often it is tried.
Capabilities by app
These are the capabilities available to grant. Powers are granted per agent on its Powers tab. Native apps are built into Annex Orbis; Integrations are third-party services you connect per org. Capabilities marked † are external communication and are approval-gated: the agent prepares the action but a human approves before anything leaves the organization.
- ·List emails
- ·Read email
- ·Mark spam
- ·Create draft
- ·Send draft †
- ·List / create / apply labels
- ·Send †
- ·Reply / reply-all †
- ·Forward †
Text (SMS)
- ·Send SMS †
- ·Read SMS thread
Phone
- ·Place outbound call †
- ·AI (Bland) call †
- ·Hold
- ·Unhold
- ·Transfer
Team chat
- ·Search messages
- ·Read conversation
- ·Post message
Tasks
- ·List tasks
- ·Create task
- ·Update task
CRM
- ·Look up contact (phone / email)
- ·List contacts
HR
- ·Search employees
- ·Upcoming birthdays
- ·Read time-off
Mail tools use a per-mailbox API key (below); the rest run over the org connection. Endpoint-level detail for the mail tools is in the API Keys reference.
Sending vs. reading mail
An agent acts on a mailbox with a per-mailbox API key. You generate a cl_live_…key for a mailbox (Mail → Settings → Domain → Mailbox → API Keys) and attach it to the agent in its Access tab, along with the mailbox address. The agent uses the key server-side — it is never exposed to the model. One key covers the whole mail surface for that mailbox; the key's scope decides how much:
Send / drafts / labels / spam
A full_access key lets the agent send, reply-all, forward (with attachments), save and send drafts, create and apply labels, and mark spam. Sending is approval-gated — it waits for a human before anything leaves the mailbox.
Reading
A read_only (or full_access) key lets the agent list and read messages — but only on open-tier mailboxes (see below).
Full endpoint reference: API Keys.
The open-tier restriction
API keys only work on open-tier mailboxes.
If you try to create a key on an end-to-end encrypted mailbox, you will see:
{ "error": "api_keys_open_tier_only" }This is not a policy we can relax. On an end-to-end encrypted mailbox the server stores ciphertext only — it has no key and cannot read the contents. There is nothing for an API key to unlock, so an agent can never read that mailbox no matter how it is configured.
Open tier
Server-readable. Supports API keys, agent reads, fast header lists, and search. Treat contents as org-confidential.
E2EE tiers
Zero-access. No API keys, no agent reads. Choose this when a mailbox must never be machine-readable — and note that agents cannot triage it.
Full detail in the encryption tiers guide. Choose the tier when you create a mailbox — changing it later means re-creating the mailbox.
Adding a read key
- In the mail app, open Settings → API keys for the mailbox you want the agent to read.
- Create a key with
read_onlyscope unless the agent also needs to manage the mailbox. - Copy the
cl_live_…value — it is shown once. - In the agent's Access → Mailboxes section, choose the mailbox and paste the key.
The agent stores the key server-side and never returns it to a browser afterwards — only the last four characters, so you can tell which key is in place. Full API reference in the API keys guide.
Who did what
Every change is recorded with what kind of thing made it — a person, an agent, or an automation — along with which one, and what it was called at the time. An agent's own name is stored alongside the record, so the trail stays readable even after the agent is renamed or removed. Where an agent acted because a person asked, both are kept.