The shape of a request #
Every API route is POST, takes JSON, returns JSON and lives under /v1. You authenticate with Authorization: Bearer <token> unless the row says otherwise. An error comes back as {"error": "..."} with a status that means what it says: 401 for no credential, 403 for a credential without the grant, 409 for a guard refusing, 429 for a rate limit, 400 for a request that does not parse.
A token comes from ns-brain hive login or from enrolment. It belongs either to a person or to a grant of its own. A person's token always has that person's role at the moment it is used, so demoting somebody demotes every token they hold.
Routes with no credential #
Each of these has to work without a credential: a machine that has never enrolled cannot hold a token and somebody creating the first organisation has no account yet.
| Route | What it is |
|---|---|
| GET /v1/health | Whether the server is up, which schema and which embedding model. |
| GET /llms.txt | The docs, for an agent that was handed a URL and nothing else. |
| GET /docs | The full client and server reference, served by the hive itself so a customer who only ever visits that server still has it: adding projects, machines and people, every command and flag, roles and error messages. |
| POST /v1/enrol | Enrolment with a password. Takes an email, a password and a certificate request; returns a certificate, a token and the relay address. The machine it creates is temporary: it lasts thirty days. |
| POST /v1/enrol/request POST /v1/enrol/claim | The first and last steps of permanent enrolment. Neither grants anything by itself: the approver grants it, on the route that does need a credential. |
| POST /v1/machine/renew | Authenticated by the certificate being renewed, not by a token, because the machine that most needs to renew (the relay) holds no token at all. Refuses a temporary machine. |
| POST /v1/device/start POST /v1/device/poll | The first steps of the device flow: how somebody with no credential gets one. It hands out a code and nothing else. |
| POST /v1/signup | Creates an organisation and sets its owner's password, which is used to sign in to the dashboard. Refuses an address that already has an account. Rate limited in the store and off unless the operator started the server with --signup. |
Memory and session #
The routes a normal session uses. Everything here is limited to the nodes the credential can reach, inside the query itself, not filtered afterwards.
| Route | What it is |
|---|---|
| POST /v1/recall | Ranked search. If a match was replaced it returns the replacement, so a question in the old wording gets today's version. |
| POST /v1/remember | Saves one memory. A memory is identified by node, scope and normalised title, so saving it again improves it instead of making a copy and the guards refuse instead of overwriting. |
| POST /v1/memory/get | One memory by id, with its provenance. |
| POST /v1/memory/update | Edits one. Renaming it onto another memory's identity is refused. |
| POST /v1/memory/forget | Deletes one, leaving a tombstone. Without force it refuses a pinned memory and one that replaces others. |
| POST /v1/memory/verify | Marks a memory as re-checked today. |
| POST /v1/log POST /v1/events | Adds an activity event and reads the recent ones back. |
| POST /v1/brief | The session brief: guardrails, preferences, pins, what is due, the inbox, recent activity. It has a size budget and says what it cut. |
| POST /v1/session/end | What this session wrote. The Stop hook reports on it. |
| POST /v1/task | Tasks: add, list, due, done, drop, wait, reopen, set, snooze. An unknown action is a 400. |
| POST /v1/feedback/register | No credential. Emails a 6-digit code to the address so a local brain can send feedback. One an hour per caller address; refuses a banned address. Returns 501 when the server has no recipient or no mail. |
| POST /v1/feedback/verify | No credential. Swaps the code for a feedback credential the server generates. Registering the same address again rotates the credential for the same sender. |
| POST /v1/feedback/send | Takes a feedback credential or a hive token. Stores one item for the recipient. Limits: 8 KB, the secret scan, 5 open items and 10 sends a day per sender and per address. Hitting a limit returns 429. |
| POST /v1/feedback/mine | The caller's own items, their state and every reply. peek counts unseen replies without marking them read. |
| POST /v1/feedback/forget | Feedback credential only. Erases the registration, items and replies. A ban stays in place. |
| POST /v1/feedback/admin | Only for the recipient project, as curator: inbox, read, reply, close. Anything else returns 403. |
| POST /v1/traits POST /v1/whoami | What the brain knows about the user. Kept per person, not per machine, shown only when asked for and every line carries the evidence behind it. |
| POST /v1/export | Every memory, event, link and provenance field for one project or one organisation. The refusals point here and hive leave uses it. It still works while an organisation is suspended and when its balance is empty. |
| POST /v1/snapshot | A readable summary of the store, per scope. |
| POST /v1/nodes | The part of the tree this credential can reach. |
Reports #
Read-only views of what is already stored. They add no state.
| Route | What it is |
|---|---|
| POST /v1/stats | Counts by type, tier, scope and age. |
| POST /v1/map | The shape of the store: scopes, pins, recent tombstones, measures. |
| POST /v1/coverage | What this brain holds near a subject, for when a search finds nothing. |
| POST /v1/review | What is stale, what is due for a re-check and duplicates. |
| POST /v1/doctor | The server's check of the whole database: replacement links that point nowhere, orphans, index drift. |
Machines and people #
| Route | What it is |
|---|---|
| POST /v1/machines | What is enrolled here. |
| POST /v1/machines/revoke | Revokes one. The relay refuses it within a minute, the credential it was given is revoked with it and its name can never be used again. |
| POST /v1/token/revoke | Revokes the credential this request came with: how a device signs itself out for good (ns-brain hive logout --revoke). Every call after that is refused. |
| POST /v1/enrol/pending POST /v1/enrol/approve | What is waiting for approval and admitting one permanently from a machine you already have. |
| POST /v1/device/approve | Lets a person in: their code, their email, the node and the role. An owner with guardrail or axiom authority can pass either on with guardrail / axiom. Approving the same person again updates their grant instead of adding a second one. |
| POST /v1/password | Set the password that enrols a new machine. |
| POST /v1/dashboard/session | Creates the one-time code that opens the dashboard in a browser. |
Compliance #
Owner on the organisation, except settings, which needs admin on the node. That rule is what keeps settings safe. A node's settings start as a copy of its parent's and then belong to the node, so the only thing stopping a team from loosening its parent's retention is that it cannot reach this route. Each has a command: ns-brain hive retention, erase, hold, settings.
| Route | What it is |
|---|---|
| POST /v1/admin/retention | Runs one organisation's own retention rules. A dry run unless apply and it lists what would go before anything does. Nothing that replaces another memory is ever deleted on a schedule. |
| POST /v1/admin/erase | Removes what one person wrote and their name on it. Returns 409 when a legal hold blocks it and the result comes back with the refusal so the caller can see what would have gone. A memory that retracts another is anonymised, not deleted. |
| POST /v1/admin/hold | Puts a legal hold on a node, or lifts one by id. A hold beats an erasure request: the request is queued and the requester is told so. |
| POST /v1/admin/settings | Reads or replaces a node's retention map, sensitivity and how long audit rows live. It replaces the whole record instead of merging, so send all of it. |
| POST /v1/admin/embed | Runs an embedding sweep now. Embedding runs in the background on purpose, so something has to set it going. |
Browser routes #
These sign in with a cookie instead of a bearer token. A browser can be tricked into sending a credential, which is a different risk from an agent holding one on purpose. Writes check the Origin header and the account sections need admin.
| Route | What it is |
|---|---|
| GET /dashboard | The organisation: seats, billing, people, credentials and letting the next person in. Billing, people and credentials need admin; below that, those sections say so instead of showing. |
| GET /dashboard/browse | Browse the memories and nodes the signed-in credential's grant reaches, decrypted on the server. A node outside the grant returns nothing. Read only: writing stays in the CLI, MCP and the web UI, where the guards are. |
| GET /dashboard/memory | One memory's full body by id, only when it sits in a node the caller may read. |
| POST /dashboard/approve | Approves a device code typed in by hand. Pending codes are not listed, on purpose: whoever approves a code decides which brain that person lands in, so the code has to come to you from them. |
| POST /dashboard/role | Changes a person's role on one node, up or down, with no new login. You cannot set a role above your own, the last owner cannot be demoted and each change is logged as an access event at the org root. |
| POST /dashboard/password | An admin sets their own password from the dashboard, giving the current one if there is one. Password sign-in at /login is only for admins and owners; anybody can still use the same password to enrol machines. |
| POST /dashboard/revoke | Revokes a credential. The query is limited to the caller's organisation, because an id from a form is a number a stranger can also type. |
| POST /dashboard/topup | Starts a card topup of $10 to $500 into the wallet. Needs admin. Sends the browser to Stripe's checkout page and credits nothing itself, because coming back from Stripe is just a link and a link can be reloaded. |
| POST /billing/stripe | Stripe's webhook and the only route that adds money to the wallet. Refuses anything whose Stripe-Signature does not verify, credits a paid checkout once however often it is delivered, then takes what is owed from it. A refund takes back what it returned. |
| POST /dashboard/logout | Signs out. Deletes the session on the server, so a copied cookie stops working too, not only the one in this browser. |
| GET /login POST /login | Signs in with the email and password chosen at signup. Ten wrong passwords for one address, or from one place, lock sign-in for fifteen minutes. A wrong password and an unknown address get the same answer. |
| GET /signup GET /v1/device | The pages a person lands on with no credential. |
| GET / | Tells whoever opened the server in a browser what it is. |