Blog / How-to guides

Talk to a Semurg node over plain HTTP: addresses, the token, answers and errors

12 October 2026 · Semurg · 4 min read · Markdown

Verified: every command below ran on a fresh node of r11.78.20261012.bc0d94f (how)

connectionsrestapiauthhow-to

Every Semurg node answers plain HTTP. There is no client library you must use and no account to create: a node, its address and its API token are the whole setup. This post covers the rules every REST call follows. The other connections (the MCP endpoint, the WebSocket, the client libraries) are covered in their own posts and answer the same questions the same way, because each capability has one implementation behind every door.

Health and version answer anyone with no token; every data, memory, status and cluster route needs the node's token, in either header.No token neededNeeds the tokenYour callHealthVersionThe query routeThe memory routesStatus and clusterroutesHealth and version answer anyone with no token; every data, memory, status and cluster route needs the node's token, in either header.No token neededNeeds the tokenYour callHealthVersionThe query routeThe memory routesStatus and clusterroutes

The address

A node listens on http://localhost:4000 on the machine it runs on, and only there, until you decide otherwise. The routes fall into two families:

  • Public routes that say whether the node is up and which release it runs: /api/health and /api/version. They need no token.
  • Everything else: your data, memory, queries, the node's status, on routes whose path begins with v1, such as /v1/query. Every one of them needs the token.

The full list of routes, with every operation, is in the API reference, which is generated from the code of the published release.

The token

The installer prints the node's API token when it finishes, and keeps it on the node in /etc/semurg/semurg.env; a Docker node prints it in its log and keeps it in the container. Send it with every call to a v1 route, in either header:

  • Authorization: Bearer <token>
  • x-api-key: <token>

Without it, such a call is refused with 401; with it, the same call goes through:

bash
export SEMURG_API_TOKEN=<your token>
curl -si http://localhost:4000/v1/whoami | head -1
curl -si -H "Authorization: Bearer $SEMURG_API_TOKEN" http://localhost:4000/v1/whoami | head -1

Expected: the first call answers HTTP 401, the second HTTP 200

A refusal tells you what to do

A refused call answers JSON with "ok": false, an error that says what was wrong and, where there is more to say, a detail. The 401 goes further, because the usual question is not "which header?" but "where is my token?": it says what your request carried, how to send the token, and where to find it.

bash
export SEMURG_API_TOKEN=<your token>
curl -s http://localhost:4000/v1/whoami

Expected: a refusal that says what the request carried, how to send the token, and where to find it

If your shell variable is empty, the 401 says that too: an empty token is the most common mistake, and the answer names it rather than pretending the header was missing. On a node exposed to other machines, the answer no longer says where the token file is; it tells a stranger to ask the operator.

The other statuses follow the same pattern: 422 for a call whose body is wrong, naming the field; 404 for something that is not there; 409 for a request that cannot be completed as asked; 413 for a call past a size bound; 501 for a capability this release does not carry; 503 for something that could not be read or done right now, safe to retry.

An answer

A successful call answers JSON with "ok": true and the fields of that operation. With the token, whoami says who the node thinks you are:

A call to a data route is checked for the token first; without it the node refuses and says where the token is; with it the call reaches its operation, which answers ok true with its fields or ok false with an error and a detail that names what to change.Your callToken checkRefused: says whereyour token isThe operationok true: theoperation's fieldsok false: error anddetail name the fixmissing or wrongvalid
bash
export SEMURG_API_TOKEN=<your token>
curl -s -H "Authorization: Bearer $SEMURG_API_TOKEN" http://localhost:4000/v1/whoami

Expected: an authenticated answer naming your scope of access

One route for every kind of data

Most reads and writes of data go through one route, POST /v1/query, with an op naming the operation and the operation's own fields beside it. An unknown op is refused with the nearest real one suggested and the full list of operations, so a typo answers with its own fix. The memory calls have their own routes, such as /v1/memory/recall, and the node's own state is at /v1/status and on the cluster routes, such as /v1/cluster/util.

Behind your own proxy

To reach a node from other machines, put it behind your own TLS proxy and use the proxy's https address; every path stays the same. A node without a token that is reachable from other machines serves callers there only a small public sandbox, never your data, so set a token before you expose a node that holds anything private.

Next

How these commands were checked

Our test farm ran each of the 3 command blocks marked runnable, exactly as written, with the answer checked against the expectation printed under it, against a fresh node of the published release r11.78.20261012.bc0d94f. A post is published only when every one of them passed there.

Related