Skip to content

Pre-release. v0.1 is not out yet, so there is nothing to install and no public source to clone — the quickstart builds from a checkout.

Endpoints

Every route the control plane serves. The contract for each is in the v0.1 API surface.

No credential.

Method Path Returns
GET /.well-known/openid-configuration Discovery: the issuer, the three OAuth endpoints, the JWKS URL, the grant types and the one client authentication method
GET /.well-known/jwks.json The public keys task tokens and audit checkpoints are signed with. Every configured key is published; only the active one signs
GET /agents/{agent_id}/jwks.json An agent’s inline public keys. 404 when the registration uses jwks_uri instead

A disabled agent still publishes its keys, so tokens it was already issued can still be checked.

Method Path Authenticated by Does
POST /oauth2/token The agent’s private_key_jwt assertion Exchange a user’s token for a task token, or refresh with a task grant
POST /oauth2/introspect The token itself Whether the token is active, answered from storage
POST /oauth2/revoke The agent’s private_key_jwt assertion Revoke a task token by jti, or a task grant, which revokes its task
  • grant_type=urn:ietf:params:oauth:grant-type:token-exchange starts a task; grant_type=refresh_token renews one. Your first exchange describes the response.
  • Introspection asks for no client credential in v0.1. It tells the holder nothing the token does not already say, except whether it has been revoked.
  • Revocation follows RFC 7009. Only the agent a token was issued to can revoke it. Any other token, including one that does not exist, gets the same empty 200.

Every admin route takes Authorization: Bearer <admin API key>. If SubactId:Admin:ApiKey is not set, every admin route answers 503. A wrong key gets 401 and writes admin.denied. See the admin API.

Method Path Result
POST /admin/agents 201 with the agent; 400 with per-field errors; 409 if the id exists
GET /admin/agents 200 with every agent
GET /admin/agents/{agent_id} 200; 404
PATCH /admin/agents/{agent_id} 200 with the updated agent, validated as a whole; 400; 404
DELETE /admin/agents/{agent_id} 204; 404; 409 while any of the agent’s tasks is still stored
DELETE /admin/agents/{agent_id}/tasks 200 with {"revoked_tasks": n}; 404
DELETE /admin/tasks/{task_id} 200 with {"revoked_tasks": n}; 404
GET /admin/sponsors/{sponsor_key} 200 with the block on that human; 404 if not blocked
PUT /admin/sponsors/{sponsor_key}/block 200 with the block and revoked_tasks: live tasks end and no new one starts until the block is lifted
DELETE /admin/sponsors/{sponsor_key}/block 204; 404 if not blocked; 409 if another source placed the block
DELETE /admin/sponsors/{sponsor_key}/tasks 200 with {"revoked_tasks": n}: ends live tasks without blocking
GET /audit 200 with one page of the ledger; 400 with per-field errors
GET /audit/checkpoints 200 with one page of checkpoints, oldest first
GET /audit/records/{seq}/proof 200 with one record’s proof; 404 until sealed; 410 once archived

A sponsor_key is the value of the claim named by SubactId:UpstreamIdp:SponsorKeyClaim, sub by default. Kill switches are idempotent; see revocation.

Each receiver exists only when it is configured. Otherwise its path answers 404.

Method Path Authenticated by Does
POST /backchannel-logout The identity provider’s signature on the logout token Back-channel logout: ends the tasks a session started, or all of a person’s tasks. Does not block
various /scim/v2/Users A SCIM bearer credential (SubactId:Scim:BearerToken) SCIM 2.0 provisioning: a deactivated or deleted user is blocked and their tasks end
POST /events A push credential and the transmitter’s signature on the event Shared Signals: CAEP and RISC events end tasks, and account events block or unblock the person
Method Path Meaning
GET /healthz The process is up
GET /readyz 200 once the database answers, the signing key is loaded, the identity provider’s keys have been fetched, and this month’s ledger partition exists; 503 until then

Point a load balancer at /readyz and a restart policy at /healthz.

If the identity provider stops answering after the instance is ready, /readyz stays 200, because the instance still holds the provider’s keys and can keep serving. Once the last successful key fetch is more than fifteen minutes old, the body reads Degraded. Do not route on Degraded. Operating it covers what to alert on.

Every route except /healthz and /readyz is rate-limited per source and can answer 429 slow_down with Retry-After. Introspection, the signal receivers and everything else use separate buckets. See configuration.

Subact ID Pre-release. v0.1 is not out yet.

© 2026 Nikola Živković PR Agencija za programerske usluge Novi Sad. Subact ID is its product.

LegalTermsPrivacy