Docs ยท HTTP API

Forty-eight routes,
and one of them was documented.

Everything ns-brain does against a server it does over these and until now only /v1/health appeared anywhere — including /v1/export, which the refusals themselves tell you to go and use. The CLI is the supported client and none of this is needed to run a brain. It is here because an API nobody can read is an API nobody can leave.

The shape of a request #

Every API route is POST, takes JSON, answers JSON and lives under /v1. Authentication is Authorization: Bearer <token> unless the row below says otherwise. An error is {"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, 400 for a request that does not parse.

A token is minted by ns-brain hive login or by enrolment and carries either a person or a grant of its own. A credential belonging to a person has that person's role at the moment it is used, so demoting somebody demotes every token they hold.

The CLI is the client. Every route here has a command in front of it and the command carries the guards, the dry runs and the queue. Calling the API directly is supported and unwrapped: nothing below will stop you doing something the command would have refused.

Routes with no credential #

Six of them and each is a case where requiring one would be a contradiction: a machine that has never enrolled cannot hold a token and somebody creating the first organisation is by definition nobody yet.

RouteWhat it is
GET /v1/healthIs the server there, which schema, which embedding model. The one route that was documented.
GET /llms.txtThe docs, for an agent that was handed a URL and nothing else.
GET /docsThe full client and server reference, served by the hive itself so a customer who only ever visits that server has it: adding projects, machines and people, every command and flag, roles and error messages.
POST /v1/enrolPassword enrolment. Takes an email, a password and a certificate request; answers a certificate, a token and the relay address. The machine it creates is temporary: thirty days.
POST /v1/enrol/request
POST /v1/enrol/claim
The permanent path's first and last legs. Neither grants anything on its own — the authority is the approver's, on the route that does take a credential.
POST /v1/machine/renewAuthenticated by the certificate being renewed rather than 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 device flow's first legs: how somebody with no credential gets one. Hands out a code and nothing else.
POST /v1/signupCreates an organisation and sets its owner's password, which signs 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 an ordinary session uses. Everything here is scoped to the nodes the credential can reach, in the query rather than after it.

RouteWhat it is
POST /v1/recallRanked retrieval. Resolves a match onto the memory that replaced it, so a question in the retracted wording answers with today's version.
POST /v1/rememberStore one. Identity is node, scope and normalised title, so re-remembering refines rather than duplicating and the guards refuse rather than overwrite.
POST /v1/memory/getOne memory by id, with its provenance.
POST /v1/memory/updateEdit one. Renaming onto another memory's identity is refused.
POST /v1/memory/forgetDelete one, leaving a tombstone. Refuses a pinned memory and one that supersedes others without force.
POST /v1/memory/verifyMark a memory re-checked today.
POST /v1/log
POST /v1/events
Append an activity event and read the recent ones back.
POST /v1/briefThe session brief: guardrails, preferences, pins, what is due, the inbox, recent activity. Budgeted and it names what it cut.
POST /v1/session/endWhat this session wrote, which is what the Stop hook reports on.
POST /v1/taskTasks: add, list, due, done, drop, snooze.
POST /v1/traits
POST /v1/whoami
The user model. Per person rather than per machine, shown on demand, every line carrying the evidence that produced it.
POST /v1/exportEvery memory, event, link and provenance field for one project or one organisation. This is what the refusals point at and what hive leave uses. It works while an organisation is suspended and with an empty balance.
POST /v1/snapshotA readable digest of the store, per scope.
POST /v1/nodesThe part of the tree this credential can reach.

Reports #

All read-only groupings over what already exists. They add no state, which is why they were the cheapest commands to give a remote form.

RouteWhat it is
POST /v1/statsCounts by type, tier, scope and age.
POST /v1/mapThe shape of the store: scopes, pins, recent tombstones, measures.
POST /v1/coverageWhat this brain holds near a subject, from the other side of a recall miss.
POST /v1/reviewWhat is stale, what is due to be re-confirmed and duplicates.
POST /v1/doctorThe server's report on the whole database: dangling supersession links, orphans, index drift.

Machines and people #

RouteWhat it is
POST /v1/machinesWhat is enrolled here.
POST /v1/machines/revokeRevoke one. It is refused at the relay within a minute, the credential it was issued is revoked with it and its name is retired for good.
POST /v1/token/revokeRevoke the credential this request arrived with: how a device signs itself out for good (ns-brain hive logout --revoke). Every call after it is refused.
POST /v1/enrol/pending
POST /v1/enrol/approve
What is waiting for approval and admitting one permanently from a machine you already hold.
POST /v1/device/approveLet a person in: their code, their email, the node and the role. An owner who holds guardrail or axiom authority may pass either on with guardrail / axiom; a second approval of the same person updates their grant rather than adding one.
POST /v1/passwordSet the password that enrols a new machine.
POST /v1/dashboard/sessionMint 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 permission is the guarantee, because settings are seeded from the parent and then owned and what stops a team loosening its parent's retention is that it cannot reach the route. Each has a command now: ns-brain hive retention, erase, hold, settings.

RouteWhat it is
POST /v1/admin/retentionSweep one organisation's own rules. A dry run unless apply and it names what would go before anything does. Nothing that supersedes another memory is ever deleted on a schedule.
POST /v1/admin/eraseRemove what one person wrote and their attribution. Answers 409 when a legal hold refuses it and the result travels with the refusal so the caller can see what would have gone. A memory that retracts another is anonymised rather than deleted.
POST /v1/admin/holdPlace a legal hold on a node, or lift one by id. A hold outranks an erasure request: the request is queued and the requester is told it is queued.
POST /v1/admin/settingsRead or replace a node's retention map, sensitivity and audit-row lifetime. It replaces rather than merges, so send the whole record.
POST /v1/admin/embedRun an embedding sweep now. Embedding is asynchronous by design, so somebody has to drive it.

Browser routes #

These authenticate with a cookie rather than a bearer token, because a credential a browser can be tricked into sending is a different threat from one an agent holds deliberately. Writes check the Origin header and the account sections need admin.

RouteWhat it is
GET /dashboardThe organisation: seats, billing, people, credentials and letting the next person in. Billing, people and credentials need admin; below that the sections say so rather than rendering.
GET /dashboard/browseRead 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/memoryOne memory's full body by id, only when it sits in a node the caller may read.
POST /dashboard/approveApprove a device code typed in by hand. Pending codes are deliberately not listed: whoever approves one decides which brain that person lands in, so it has to reach you from them.
POST /dashboard/revokeRevoke a credential. Scoped to the caller's organisation in the query, because an id from a form is a number a stranger can also type.
POST /dashboard/topupStart a card topup of $10 to $500 into the wallet. Needs admin. Sends the browser to Stripe's checkout page and credits nothing itself: coming back from Stripe is a link and a link can be reloaded.
POST /billing/stripeStripe's webhook and the only route that credits the wallet. Refuses anything whose Stripe-Signature does not verify, credits a paid checkout once however often it is delivered, then takes what is due from it. A refund takes back what it returned.
POST /dashboard/logoutSign out. Deletes the session on the server, so a copied cookie stops working as well as the one in this browser.
GET /login
POST /login
Sign in with the email and password chosen at signup. Ten wrong passwords for an address, or from one place, lock sign-in for a quarter of an hour. 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 /What the server is, for whoever opened it in a browser to find out.