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.
Built by Qcentic