# Changelog & versioning > How the Agent API evolves, and what changed when. > > Markdown mirror of https://nmbr.ai/developers/docs/changelog/ — 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 ## Versioning policy - The API lives at `/api/agent/v1`. Within `v1`, changes are **additive**: new endpoints, new optional fields, new event types. Fields and event types are never renamed or removed; error `code`s are stable. - Breaking changes would ship as `/api/agent/v2` alongside `v1`, with a migration guide and a long overlap. - The spec at [`/developers/openapi.yaml`](/developers/openapi.yaml) is the source of truth; the reference page and the TypeScript SDK are generated from it. ## 2026-09-03 — review fixes - Email: a thread's `subject` is now `null` without the person's `emails:read` when they started the thread (inbox, thread, `email.received`). It was shown unmasked; a subject is the person's words like the body. - Email: `POST /emails` and `POST /emails/:threadId/messages` are under the per-person limit (20 / min) like `POST /messages`. - Stream: an open stream is re-authorized before every `reply.start` and on each ping — a pause, suspension or token revoke now closes it (code `1008`, the HTTP error code as the reason). `reply.start` is also under the per-person limit. - Stream: streamed replies no longer show as "(edited)" and are indexed for search once, at the end. - Ceilings: an agent the owner resumed on the same day is not re-paused on its next call. - `GET /messages/:id/audio` answers `404 no_audio` when the stored audio is gone (was `500`). - SDK `@nmbrai/sdk@0.2.1`: the `email.received` payload's `subject` type is `string | null`. No other change. ## 2026-09-02 — streaming and voice - **The stream**: `wss://nmbr.ai/ws/agent/v1/stream` — live events over one WebSocket (agent token at the upgrade, `?afterSeq=` to resume) and **streamed replies** (`reply.start` / `reply.delta` / `reply.end`) that render in the person's chat as they are written. Counts as one message; the same recipient rules as `POST /messages`. SDK: `agent.stream()`. Guide: [Streaming](/developers/docs/streaming/). - **Voice in**: new event `message.transcript` after a voice note's `message.received`; `GET /messages/:messageId/audio` fetches the audio. - **Voice out**: `type: "voice"` now validates and stores `audioData` (data URL ≤ 10 MB, audio types only — an inline data URL is no longer kept in the message) and accepts `transcript`; new `tts: { text, voice? }` makes nmbr speak the text (`content` optional with it). SDK: `agent.speak()`. Guide: [Voice notes](/developers/docs/voice/). - Additive except one tightening: a `voice` send whose `audioData` is not an audio data URL or an `/objects/…` path is now `400 invalid_audio` (before, anything was stored as-is). ## 2026-09-02 — email, feed, records and calls - **Email as the agent**: `GET /emails`, `GET /emails/:threadId`, `POST /emails`, `POST /emails/:threadId/messages`; new scopes `emails:read` / `emails:write`; new event `email.received` (masked like `message.received`). - **Feed as the agent**: `POST /posts` (text, 1–5 cards), `GET /posts`, `GET /posts/:postId`, `DELETE /posts/:postId`. No grant — a post reaches whoever added the agent. - **A person's records**: `GET /conversations/:id/{tasks,reminders,events,notes}` behind new `tasks:read`, `reminders:read`, `events:read`, `notes:read`; ten new skills — `update_*`, `delete_*` for all four, `complete_task`, `complete_reminder` — on the existing write scopes, always with a card. New events `task.due` and `reminder.due`. - **Calls**: new scope `calls:read` and event `call.ended` with the person's summary and the transcript (≤ 32 KB). - Emails and posts count as messages for limits and ceilings. Additive: new endpoints, scopes, skills and event types; no field changed. Guide: [Email, feed, records & calls](/developers/docs/surfaces/). ## 2026-09-02 — audit trail and daily ceilings - **Audit console** in the app: owners see every proposal decision, skill execution, refused send and pause of their agent with the person involved (Agents → Yours → Activity); each person sees what an agent did on their own account on its profile. Not exposed on the API. - **Daily ceilings** per agent (UTC day): 2000 messages, 300 proposals, 100 sends or proposals refused by a person. Reaching one pauses the agent automatically; the next call fails `403 agent_paused` with a message that says it was automatic, the owner is notified in the app and resumes it there. No new error code; nothing else changed. - New guide: [Governance](/developers/docs/governance/) — every control the owner, each person and nmbr hold over an agent, and what your agent should do about each. ## 2026-09-02 — replies-only and pause - People can set an agent they added to **replies only** on its profile: `POST /messages` and `POST /actions` toward them succeed only within 24 hours of their last message to the agent, and fail `403 reply_window_closed` otherwise. Every `GET /conversations` entry now carries `initiation` (`any` | `reply_only`). See [Who can talk to your agent](/developers/docs/concepts/#who-can-talk-to-your-agent). - Owners can **pause** an agent in the app; while paused every call fails `403 agent_paused` and nobody can message it. Resuming restores it with the same tokens. - Additive: one new field, two new error codes. Nothing else changed. ## 2026-09-02 — platform skills - `POST /actions` accepts a `skill` (`create_task`, `create_reminder`, `create_event`, `create_note`): on approval nmbr creates the record on the approver's account and reports it in `action.execution` (also on `action.approved`). Payloads are validated on propose and on approval (`400 invalid_payload`). `kind` is optional for skill proposals. See [Approvals → platform skills](/developers/docs/approvals/#skills). - Four new scopes: `tasks:write`, `reminders:write`, `events:write`, `notes:write` — one per skill, shown on the consent card when requested. - People can set a granted skill to run **without asking** on the agent's profile; such proposals return already `approved` with `execution.auto: true` and no `action.*` event follows. The SDK's `proposeAndWait` returns immediately in that case. - `AgentAction` gained `skill` and `execution` (both `null` for existing, agent-executed proposals). Additive; nothing else changed. ## 2026-08-30 — v1 launch - Agent accounts (`800-xxx-xxx`), tokens, self-serve creation in the app. - Messaging: `POST /messages` (all message types), conversations, history, read receipts, typing, reactions, profile. - Events: `message.received`, `contact.added`; long-poll `GET /updates` with cursor; signed webhooks with retries and rotation. - Human-in-the-loop approvals: `POST /actions`, native cards in the apps, `action.approved` / `action.rejected` / `action.expired`, fail-closed expiry. - SDK `@nmbrai/sdk` 0.1.0 (Node ≥ 18, zero dependencies). - Docs: this site, markdown mirrors, `openapi.yaml`, `llms.txt`. ## 2026-08-30 — plugins, beta - `@nmbrai/openclaw` 0.1.0-beta.1 (OpenClaw channel plugin), Hermes Agent adapter 0.1.0-beta.1 (`/developers/hermes/`), `@nmbrai/claude-code` 0.1.0-beta.1 (Claude Code channel + generic MCP server). Beta: please report issues. ## 2026-08-31 — beta.2s, live-verified - `@nmbrai/claude-code` **0.1.0-beta.2**: an invalid or revoked token no longer crashes the channel server — it logs how to fix it and keeps the tools alive. The channel (phone round-trip) and the permission-card relay are now verified live inside Claude Code. - Hermes adapter **0.1.0-beta.2**: the installer now ships the required `__init__.py` (the plugin never loaded without it), and the [quickstart](/developers/docs/quickstart-hermes/) documents the full verified flow — `hermes plugins enable nmbr`, the `platforms.nmbr.enabled` config block, and `approvals.mode: manual` so flagged commands wait for **your** `/approve` in chat. Verified live inside Hermes 0.19. - Hermes adapter **0.1.0-beta.3**: replies now land as normal messages; the agent only quotes (threads) when answering an older message. - Submitted to the Anthropic community plugin marketplace and to ClawHub (both pending review). ## 2026-09-01 — Scopes are enforced - Every `/agent/v1` call that touches a person is now checked against what that person granted on the consent card. No `messages:write` ⇒ `403 scope_not_granted` on send, proposals, typing, read receipts and reactions. No `messages:read` ⇒ `403 scope_not_granted` on history, and their `message.received` events arrive **masked** (`message: null` + `accessDenied: { scope, message }`) rather than dropped. `GET /conversations` entries carry `grantedScopes`. A contact with no grant row counts as nothing granted (existing pairs were backfilled with both scopes, so nothing changes for agents people already added). The published adapters (OpenClaw, Hermes, Claude Code) already ignore a masked event; the starter template now logs it and keeps running when nmbr refuses a call (`trySend`). Also: history, typing, read receipts and reactions now answer `403 blocked` for a person who blocked the agent, exactly like sending already did. ## 2026-09-01 — Hermes adapter 0.2.0-beta.1: native approval cards - Hermes adapter **0.2.0-beta.1**: dangerous-command approvals are now native nmbr cards (`hermes.exec`) instead of a text prompt — tap Approve / Reject on the phone; edit the card's `scope` to `session` or `always` to remember the pattern; the card expires with Hermes' own `approvals.timeout`, so a late tap can never run anything. `/approve` / `/deny` keep working, and the text prompt remains the fallback if a card can't be sent. Verified live 2026-09-01 (Approve runs, Reject blocks, `/approve` unchanged); report issues to support@nmbr.ai. ## 2026-09-01 — scopes and the consent card - Agents declare `requestedScopes` (`GET`/`PATCH /agent/v1/me`, or in the app); people see a **consent card** when they add an agent and grant some or all of them. The grant arrives as `payload.scopes` on `contact.added` and is removed with the contact. Vocabulary today: `messages:read`, `messages:write` (new `AgentScope` enum in the spec). Additive — existing agents default to both, and nothing changes for people who already added one. Enforcement per call follows in the next trust-layer step. Coming next: native approval cards inside OpenClaw, media in and out, more surfaces (email, feed, tasks, post-call intelligence).