API reference

Hania Code API

The terminal client is built entirely on the public v1 surface, and any integrator can use the same endpoints. Authenticate with a hania_sk_ key as a bearer token; see Authentication & API keys.

Approvals and stop work the same from the console and the API, because they share one backend. A web client built on this surface can offer a Stop button and an approval card, and they behave exactly like the console's.

Endpoints

Method & pathWhat it does
GET /api/v1/botsLists the workspace's agents, to pick one to chat with.
POST /api/v1/chat/send-streamSends a turn and streams the reply as server-sent events.
GET /api/v1/chat/streamThe persistent conversation channel. Receives what happens outside your own send, including the continuation after an approval.
GET /api/v1/chat/statsToken and cost figures for a conversation - what the terminal's /cost shows.
POST /api/v1/chat/stopInterrupts the current turn. Body {"conversation_id"}; returns {"stopped"}.
GET /api/v1/hitlLists pending approvals for a conversation.
POST /api/v1/hitl/{id}/respondAnswers one approval.
POST /api/v1/machinesPairs a machine; returns its id and one-time token.
GET /api/v1/conversationsLists sessions; supports an external_user_id filter.
GET /api/v1/conversations/{id}Returns a session's messages.
POST /api/v1/conversations/{id}/truncateRemoves everything after a message - the rollback primitive.
PATCH /api/v1/bots/{id}/modelSwitches the agent's chat model.

Send a coding turn

POST /api/v1/chat/send-stream requires external_user_id, which scopes sessions to the person using your integration. Pass new_conversation to start a fresh session, or a conversation_id to continue one. For coding sessions, two extra fields say where the code work happens:

FieldWhat it does
code_machine_idThe paired machine to run file and shell operations on.
code_workdirThe project directory on that machine.

These fill the same role as the blank machine_id and workdir on the coding tool configuration - the tool config wins when it names a machine, and these apply when it leaves the choice to the caller. The reply streams as server-sent events on the response.

Approvals

When the agent proposes a write, edit, or command and the tool is set to ask, the turn pauses. The pending request appears on GET /api/v1/hitl for the conversation, with the content to review in its context - a unified diff for file changes, the command line for commands. Answer it with:

curl -X POST https://app.hania.ai/api/v1/hitl/REQUEST_ID/respond \
  -H "Authorization: Bearer $HANIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action": "approve"}'

action is approve, approve_edited, or deny, with an optional text (the reason, on a deny) and optional edited_args (corrected arguments, with approve_edited - the tool then runs your version, not the model's). The turn resumes on its own; receive the continuation on GET /api/v1/chat/stream rather than re-sending anything.

Resolve a machine key

GET /api/machines/whoami resolves a machine key to the machine it belongs to. Unlike everything above, it is authenticated by the machine key itself, as a bearer token in the Authorization header - never by a session or an API key.

curl -H "Authorization: Bearer $HANIA_MACHINE_KEY" \
  https://app.hania.ai/api/machines/whoami

On success it returns the machine's id and name. It returns 401 when the key is unknown or the machine is no longer active, which is also how a client learns the machine was removed in the console. The terminal client uses it to bind a pasted key to the exact machine you created, rather than making a new one.

Sessions, rollback, and stats

Sessions are ordinary conversations. GET /api/v1/conversations?external_user_id=… lists a user's sessions for a resume picker, and GET /api/v1/conversations/{id} returns the messages. POST /api/v1/conversations/{id}/truncate removes everything after a given message, which is what the terminal's rollback uses alongside its local file snapshot. GET /api/v1/chat/stats returns the conversation's token and cost figures.