REST API
Use this when you are building an integration against the HTTP contract: your own tooling, or a service that does not go through the CLI.
You do not need this if you use the CLI or the MCP connector; both wrap this API — start there instead.
After reading this, you should be able to form an authenticated request
against /v1/, read the error envelope, and find the route family a task
needs.
Everything the CLI and connectors do goes through one plain HTTPS + JSON API,
versioned under /v1/ and authenticated with a bearer token on every route.
A REST endpoint and its MCP tool twin are thin adapters over the same core, so
the two surfaces return byte-identical payloads.
Base URL and conventions
Section titled “Base URL and conventions”The base URL is your Spor server. Hosted teams use https://api.sporhq.io;
a self-hosted deployment uses its own origin. All routes are versioned under
/v1/ (the OAuth routes used for sign-in sit at /oauth/* — see
Authentication).
- Auth: send
Authorization: Bearer <token>on every request. Transport is HTTPS only. See Authentication for token kinds. - Content type: request and response bodies are JSON. Request bodies are
capped at 1 MB (
413 too_large). - Path parameters (node ids, project slugs) must match
^[a-z0-9][a-z0-9-]*$. - Errors: every non-2xx response carries a
{"error": {"code", "message", "details"}}envelope. See Errors and compatibility.
curl -s https://api.sporhq.io/v1/status \ -H "Authorization: Bearer $SPOR_TOKEN"Client configuration
Section titled “Client configuration”Two environment variables switch a Spor client into remote mode; unset, it
reads the local graph home directly. The legacy SUBSTRATE_* spellings are
still read (see Errors and compatibility).
SPOR_SERVER=https://api.sporhq.io # REST base (the hosted default)SPOR_TOKEN=spor_pat_... # per-user tokenSPOR_ORG=tidefall # select a stored tenant by orgspor join <token> writes the first two for you, defaulting SPOR_SERVER
to the hosted base; pass a URL (spor join <url> <token>) to point at a
self-hosted server instead.
Write semantics
Section titled “Write semantics”Every mutation is validated, attributed, serialized, and committed to the
graph’s version history. Attribution is stamped from the authenticated token
(any author: in the payload is discarded), updates require the revision
you read (a mismatch is a 409 conflict — re-read and retry, no silent
last-write-wins), and validation failures return the validator’s error list
verbatim so a calling program can self-correct. The full contract is on
Writes.
Endpoints
Section titled “Endpoints”| Method | Path | Purpose |
|---|---|---|
| GET | /v1/status |
health, node count, projects, graph head |
| GET | /v1/me |
identity echo for the bearer token |
| GET | /v1/me/org-choices |
live org membership for the held credential |
| GET | /v1/schema |
the live schema registry as data |
| GET | /v1/briefing/{project} |
a project’s briefing node |
| GET | /v1/nodes/{id} |
one node, with read-time enrichment |
| GET | /v1/nodes/{id}/history |
per-node commit lineage |
| GET | /v1/nodes/{id}/history/{sha} |
one revision’s patch and content |
| GET | /v1/commits/{sha} |
commit sha → the nodes that reference it |
| GET | /v1/changes |
recent changes to the graph (audit trail) |
| GET | /v1/queue |
the ranked decision queue |
| GET | /v1/analytics |
created-vs-completed work-flow analytics |
| GET | /v1/metrics/capture |
opt-in, redacted capture-discipline aggregates |
| GET | /v1/program/{id} |
program/progress view over blocks topology |
| GET | /v1/export |
tarball, history bundle, or auth backup — the data-exit path |
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/digest |
digest-mode compile for prompt context |
| POST | /v1/nodes |
put nodes (batch) |
| POST | /v1/nodes/{id}/edges |
add one typed edge |
| DELETE | /v1/nodes/{id}/edges |
remove one typed edge |
| POST | /v1/nodes/{id}/status |
one-scalar status update |
| POST | /v1/nodes/{id}/priority |
human priority override |
| POST | /v1/nodes/{id}/readiness |
agent-readiness override (the only hand-settable value is agent) |
| POST | /v1/nodes/{id}/commits |
link a code commit to a node |
| POST | /v1/capture |
raw text in, typed nodes out |
| POST | /v1/distill/report |
sweep telemetry (journal-only) |
| POST | /v1/corrections |
propose a standing briefing correction |
| POST | /v1/questions |
file a routed question |
| POST | /v1/gardener |
run a maintenance sweep now |
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/nodes/{id}/claim |
take the heartbeat-renewed lease |
| POST | /v1/nodes/{id}/renew |
heartbeat: bump the lease expiry |
| POST | /v1/nodes/{id}/extend |
stretch a live lease for a long idle gap |
| POST | /v1/nodes/{id}/reserve |
convert a live claim into a resumption reservation |
| POST | /v1/nodes/{id}/release |
drop the lease, return the node to the pool |
| POST | /v1/queue/claim |
claim a working set of nodes in one round-trip |
| POST | /v1/queue/renew |
heartbeat a working set (or every live claim held) in one round-trip |
| POST | /v1/queue/release |
release every live claim held, in one round-trip |
| Method | Path | Purpose |
|---|---|---|
| GET | /v1/lens/{id}/render |
render a lens or workspace (html, text, json) |
| POST | /v1/lens/{id}/ticket |
mint a read-only, expiring share ticket |
| Method | Path | Purpose |
|---|---|---|
| GET / POST | /v1/me/tokens |
list / mint your own personal access tokens |
| DELETE | /v1/me/tokens/{hash-prefix} |
revoke one of your own tokens |
| GET / POST | /v1/admin/tokens |
team-wide token list / mint (admin) |
| DELETE | /v1/admin/tokens/{hash-prefix} |
revoke any token (admin) |
| GET / POST | /v1/admin/people |
list every person / create a person subject (admin) |
| DELETE | /v1/admin/people/{id} |
offboard a member: revoke tokens and OAuth grants (admin) |
| GET / POST | /v1/agents |
list / create agents you own |
| POST | /v1/admin/agents |
create an agent for another person (admin) |
| POST | /v1/agents/{id}/token |
mint a per-session or standing agent token |
| GET | /v1/agents/{id}/tokens |
list an agent’s standing tokens |
| DELETE | /v1/agents/{id}/tokens/{hash-prefix} |
revoke one standing agent token |
| POST | /v1/agents/session |
late-bind a run session to an agent token |
| POST / GET | /v1/agents/{id}/capabilities |
publish / read machine capabilities |
| POST | /v1/agents/{id}/heartbeat |
liveness ping without a re-publish |
| GET | /v1/profiles/{id}/hosts |
match a profile against published capabilities |
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/workflows/{id}/run |
start a run of an active workflow |
| GET | /v1/work |
claimable steps across live runs |
| POST | /v1/runs/{id}/steps/{sid}/claim |
claim a ready step |
| POST | /v1/runs/{id}/steps/{sid}/complete |
report a step verdict |
| GET | /v1/runs/{id} |
the full run record |