Skip to main content

Base URL

All endpoints require the brain to be running (feral start). Responses are JSON.

Dashboard

Example: Send a command

Skills

Example: List skills

Memory

Runs MemoryStore.search_all: episodes and notes through FTS5 plus vector cosine, knowledge triples, and knowledge-graph entities, merged by score. q and query are both accepted. An empty query is a 400, never an empty result set.
degradations is the point of the payload as much as results. Each tier is isolated, so one that raises does not take out the three that answered; the failure is named here instead of silently shrinking the result set. A caller must not read count: 0 as “the store knows nothing” while degraded is true. /internal/memory/search remains as the notes-only legacy surface and also accepts either spelling of the query parameter.

Identity

Example: Ask the digital twin

Devices & Hardware

HUP device registry

GET /api/hardware/device/{device_id} answers 404 for an unknown id and 503 when there is no registry. Both used to be 200 {"error": ...}, which asserts that the body is the device: a client that stores the response as its detail state replaced the row it already had with an error object.

Access Mode & Remote Reachability

Approvals (Execution Inbox)

The approval inbox lets a non-chat client (web UI, CLI, mobile, automation) resolve pending tool-execution approvals without having to type an acknowledgement into a chat session. A pending request is created by the orchestrator whenever enforce_safety() blocks a tool call (see Autonomy Levels). Both approve and reject accept an optional JSON body:
When session_id is provided it must match the session that originated the request, or the call returns 409 session_mismatch.

Example: list pending approvals

Example: approve

Example: reject

Status codes

Checkpoints (undo file writes)

Every coding_tools__write_file and coding_tools__edit_file stashes the file’s pre-write bytes in a content-addressed store keyed by turn_id, the id shared by every tool call made while answering one user message. Git is never invoked. See Coding Harness. Omit turn_id on the revert and the most recent checkpointed turn for session_id is used. 503 when the checkpoint store cannot be opened. Without force, any file whose current content no longer matches what FERAL left there is listed under drifted and the whole revert refuses with success: false. That refusal is the point of the endpoint: a revert that silently discards somebody else’s newer edit is worse than no revert at all.
Every response carries bash_not_covered: true and a note saying so, on success as well as failure. Shell commands are not checkpointed, so anything coding_tools__bash changed in the turn is not reverted. A partial revert that reads as complete is worse than none.
feral checkpoints in the CLI deliberately does not go through these routes; it reads the same SQLite index directly, because the case you most need a revert in is the one where the brain is not answering.

Plan Mode

A per-session posture in which the agent researches and proposes but cannot mutate state. These routes live on the session resource and never touch security.autonomy_mode, which is a separate, persisted, global axis. See Plan Mode. The exit route hard-codes actor="user": it is reachable by the operator, not by the model, and the orchestrator refuses any other actor. approved is recorded for the UI and confers no privilege; every mutating call in the turns that follow still goes through the session’s autonomy mode.

Autonomy

Channels

Error Format

All errors follow a consistent shape: