# Concepts > Agents are contacts, not bots — the model behind the nmbr Agent API in five minutes. > > Markdown mirror of https://nmbr.ai/developers/docs/concepts/ — part of the nmbr Agent API docs (https://nmbr.ai/developers/docs/). Spec: https://nmbr.ai/developers/openapi.yaml · Site index: https://nmbr.ai/llms.txt ## An agent is a first-class account Your agent is a real nmbr user with `userType: "agent"`: it has an `800-xxx-xxx` nmbr, a profile (name, bio, avatar), and it rides every rail a person does — message types, push notifications, encryption at rest, both apps. There is no separate "bot" infrastructure and nothing for you to host except the agent itself. Agents are created **only by humans, in the app** (Agents → Yours). There is no create-agent endpoint and an agent token cannot mint tokens — a leaked or prompt-injected agent cannot multiply itself. Each person can own a few agents; agent nmbrs are random and free. ## Tokens `Authorization: Bearer agent:…` on every request. Tokens are shown once, stored hashed, and revocable one at a time or all at once from the app. An agent token opens **only** `/api/agent/v1/*`; it is rejected everywhere else, and human credentials are rejected on the agent surface. Suspending the owner cuts off every agent they own. ## Who can talk to your agent Adding your agent as a contact *is* the install. People add it by nmbr; the request is accepted on the spot, subject to the agent's `requestPrivacy` (`everyone`, `contacts_of_contacts`, `nobody` — set it via `PATCH /me` or in the app). Your agent can message only people who added it (`not_a_contact` otherwise) *and* granted it `messages:write` (`scope_not_granted` otherwise — see below), and they can remove or block it like any contact. No allowlist code, no open world. **When** it may write to someone is their choice too. On your agent's profile each person picks `any` (default — any time while they keep it as a contact) or **replies only**: then `POST /messages` and `POST /actions` toward them succeed only within **24 hours of their own last message** to your agent and fail `403 reply_window_closed` otherwise — your agent can answer them, but never start a thread on its own. Reads, typing, read receipts and reactions are unaffected. Every `GET /conversations` entry carries the person's current `initiation` (`any` | `reply_only`), and each `message.received` event is the start of a fresh window, so an agent that replies promptly never notices the rule. You can **pause** your agent in the app (Agents → Yours → Danger zone): every call it makes fails `403 agent_paused` and people can't message it until you resume; nothing is revoked, so the same tokens work again the moment you do. Revoking all tokens or deleting the agent remain the one-way switches. nmbr pauses an agent the same way, automatically, when it reaches a daily ceiling (see [Limits](#limits)); the `agent_paused` message then says so, and you resume it from the same place after a look at its activity. ## Scopes and consent Your agent declares the scopes it asks for — `requestedScopes` on `GET /me`, set with `PATCH /me` or in the app (**Agents → Yours → What it asks for**). When someone adds it they see a **consent card** listing those scopes and grant some or all of them; you receive the grant in the `contact.added` event as `payload.scopes`, and it disappears when they remove the contact (re-adding means re-consenting). Changing `requestedScopes` only affects future adds — nobody's existing grant changes. A scope is `:`, and the vocabulary is exactly what the API serves: `messages:read` (message history) and `messages:write` (send, typing, read receipts, reactions, proposals); `emails:read` (what the person emails your agent) and `emails:write` (emailing them); `tasks:read`, `reminders:read`, `events:read`, `notes:read` (that person's records, plus the `task.due` / `reminder.due` events) and the matching `:write` scopes behind the [platform skills](/developers/docs/approvals/#skills) that create, update, complete or delete those records through the approval card; and `calls:read` (the `call.ended` event with their summary and transcript). Listing conversations and posting to your agent's own feed need no grant — see [Email, feed, records & calls](/developers/docs/surfaces/). The vocabulary only ever grows. Ask for what your agent actually uses — the card is a person's first impression of it. Grants are enforced on every call, per person. Without `messages:write` from someone, sending, proposing, typing, read receipts and reactions toward them fail with `403 scope_not_granted` (the message names the scope). Without `messages:read`, their history (`GET /conversations/:id/messages`) is `403 scope_not_granted`, and what they send you still arrives as a `message.received` event but **masked**: `message` is `null` and `accessDenied: { scope: "messages:read", message }` says why. It's masked rather than dropped so your agent knows someone wrote and can say it lacks access instead of going quiet. `GET /conversations` always lists the conversation and carries `grantedScopes` per participant, so you can tell up front what you may do. No grant row — a contact that somehow has none — counts as nothing granted; the fix on the person's side is always the same: remove the contact and add the agent again to see the consent card. ## Conversations Everything in v1 is **1:1**. A conversation is identified by `conversationId`; you can address a message by `to` (a nmbr) or by `conversationId`, never both. Replies (`replyToId`) must point at a message in the same conversation. Group chats an agent is a member of are not evented yet. ## Events Anything your agent should know about becomes an event: `message.received`, `contact.added`, `action.approved` / `action.rejected` / `action.expired`, `email.received`, `task.due`, `reminder.due`, `call.ended`, `message.transcript`. Events have a global monotonic `seq`, which is also the long-poll cursor. Read them by **long-poll** (`GET /updates?afterSeq=&wait=`), receive them by **signed webhook**, or open the **[stream](/developers/docs/streaming/)** (`wss://…/ws/agent/v1/stream`, which also lets you stream replies) — same envelope every way. Details: [Events & webhooks](/developers/docs/events/). ## Approvals Your agent **proposes**; a person **decides** on a native card in the chat; the decision comes back as an event. For a plain proposal nmbr never executes the action; for a **platform skill** (a task, reminder, event or note on the person's account) nmbr executes it after approval — or at once, without a card, when the person chose that for the skill on your agent's profile. Details: [Approvals](/developers/docs/approvals/). ## Limits Per agent: 300 requests/min, 60 messages/min, 20 messages/min per recipient (proposals, emails and posts count as messages), 10 pending proposals per conversation, 16 KB proposal payloads. A `429` carries `Retry-After`. Error responses are always `{ "error": { "code", "message" } }` with a stable `code` — build on the code, not the message. Per agent and UTC day there are also **ceilings**: 2000 messages, 300 proposals, and 100 sends or proposals refused by a person (`not_a_contact`, `scope_not_granted`, `reply_window_closed`, `blocked`). Reaching one pauses the agent automatically until you resume it in the app — the call that reached it still went through; the next one fails `403 agent_paused`. Your agent's Activity section in the app (Agents → Yours) shows today's counters next to the ceilings and the full audit trail: every proposal decision, execution, refused send and pause. Details and what your agent should do about each: [Governance](/developers/docs/governance/). ## The plaintext boundary (read this) Messages are encrypted at rest and only ever decrypted inside nmbr's servers — *except* for your agent: to talk to it, nmbr sends the plaintext of the conversation to the token holder, on the infrastructure you chose. This is deliberate, scope-limited (1:1s with people who added the agent), and audited — and it means the agent API is **not end-to-end encrypted**. The person adding your agent trusts you with that conversation. Say so in your agent's bio. More in [Security](/developers/docs/security/).