HTTP Surfaces
Actana Control has three HTTP surfaces, and none is a public integration API. There is no POST /api/projects/:id/tasks — that HTTP task API is retired and those routes do not exist. Writes travel as core-link mutation frames. Third parties type against @actana/sdk.
1. Panel — Operator browser
The Panel's HTTP plus its panel link serve the Operator's tab. Auth is the session cookie. There is no bearer-token mode and no versioning promise. Harnesses never call it.
Task, project, and session reads and writes do not appear here: each Core owns that state. What remains is Panel-local: liveness (GET /api/healthz), Operator auth, the Core registry, project presentation and groups, preferences, usage, SSE (GET /api/events), and GET /api/update-check. Treat that list as a map, not a contract.
2. Core hook receiver — loopback
Each Core runs a small HTTP server so harnesses it spawned can report what they are doing. Not operator-facing. Nothing to configure: the Core writes hook entries into each harness's config and hands credentials in the PTY environment.
| Property | Value |
|---|---|
| Bind | 127.0.0.1 only — never the Core's public host |
| Port | Ephemeral (listen(0)), chosen at boot |
| Route | POST /api/hooks/<slug>?taskId=…&hookEvent=… |
| Auth | Authorization: Bearer — 32 random bytes minted per boot, in memory, never persisted |
| Env | AC_HOOK_URL, AC_HOOK_TOKEN, AC_HOOK_TASK_ID |
A restart mints a fresh token, so a hook from a previous boot fails auth — that session's process is gone.
3. Core file routes — mTLS HTTPS
/v1/... answers on the same HTTPS server the core-link WebSocket is mounted on: one port, one certificate, one bearer, two protocols. File bytes cross here, never over the core link. Auth is the pinned client certificate and Authorization: Bearer <bearer>. Announced as files: { version: 1 } on ready; absent means no file surface.
| Route | Does |
|---|---|
GET /v1/projects/:projectId/files?path= |
file bytes, or a directory as streamed tar |
PUT /v1/projects/:projectId/files?path= |
write a file, or unpack a tar |
GET /v1/projects/:projectId/files/list?path= |
tree as chunked NDJSON |
Type project.files.* on the SDK, not these URLs.
Pairing redeem
POST /v1/pair/redeem is the only pre-auth route on a Core. A client compares the CA fingerprint before sending the code, then posts a CSR. The private key is born on the client and never crosses the wire. Enrollment is a short pairing code, not a pasted blob.
See also
- Filesystem — why bytes are on HTTPS.
- Write path — mutations are frames, not REST.
- SDK — the surface to write against.
- Pairing — mint and redeem a code.