Skip to content

HTTP API

Everything the PiCode UI does, it does over an HTTP JSON API served by the same daemon you can talk to yourself. The reference below is not hand-written documentation: it is generated from the server's route registration, so it can never describe an endpoint the binary doesn't serve — or miss one it does.

Browse it

The full reference lives in Scalar's viewer:

Open the API reference →

Every operation shows its method, path, and grouping (workspaces, agents, sessions, automations, terminals, backup, …). Authenticated requests use the same session your browser already has after pairing.

Raw spec

  • api/openapi.json — OpenAPI 3.1, 200+ operations, regenerated by make openapi
  • llms.txt — a machine-readable map of this whole site, including the spec, for LLM consumption

Call it yourself

Pair once (the same pairing your browser uses — see Security and pairing), then reuse that session cookie:

bash
# Pair a shell: prints a URL to approve in your browser (valid 10 minutes)
picode pair

# With an approved session cookie, list your workspaces
curl -b "picode_session=<secret>" http://127.0.0.1:8445/api/workspaces

Ungated mode

For scripting against a throwaway instance, set Who must pair to Off (PICODE_AUTH_MODE=off does the same from the environment). Plain PICODE_INSECURE=1 only disables TLS — pairing still applies.

File Tree folder precondition

File Tree requests can include root, the canonical folder returned by GET /api/{agents|terminals|workspaces}/{id}/browse. Browse, text (GET and PUT), blob, gitstatus, gitdiff, git/blob and reveal compare it with the folder resolved through that owner. A mismatch returns 409 before the operation. This prevents a terminal directory change from redirecting an open file's relative path. The parameter cannot select a different folder to access.

Requests without root continue to resolve the owner's current folder. See Files and changes for the browser workflow.

Why generated

The spec is produced by cmd/picode-openapi, which walks the same registerAll call the binary makes at startup. CI re-runs the generator and byte-compares the result with the committed spec (make docs-check): a route added in Go without regenerating the spec fails the build, exactly like a UI change without fresh screenshots.