Skip to main content
32 routes. Every example runs with LITMUS_URL, LITMUS_TOKEN and LITMUS_ORG (your org tag) set in your shell (see Authentication). A $NAME in a path is an id you read from the listing route on this page; a <field> in a body is a value you supply, and every field the handler reads is shown, so send only the ones you need. Fields are what the handler’s source reads and writes, listed mechanically; they are not a schema.

GET /v0/orgs/{orgtag}/delivery

GET /v0/orgs/{org}/delivery: one row per channel in D3’s order — Slack, PR comment, Datadog, email, download — each {channel, on, state, reason, target, recommended, last_send}. The state is computed now from the installs and credentials this workspace holds (delivery.channels): ready, not_connected, read_only, no_key or unknown. Nothing is on until a member turns it on, the recommended channel included. Path parameters: orgtag Response fields written in the helper the handler answers through: channels, finding, org, recommended, tier

GET /v0/orgs/{orgtag}/delivery/log

GET /v0/orgs/{org}/delivery/log?limit=: every send, newest first — who, when, the channel, the finding’s group and the external ref (permalink, Slack ts, Datadog event id). Append-only, on disk per org. Path parameters: orgtag Query parameters the handler or its helper reads: limit Response fields written in the handler: log, org, tier

POST /v0/orgs/{orgtag}/delivery/confirm

POST /v0/orgs/{org}/delivery/confirm with {member, channel, group, target?}: a single-use, ten-minute confirm that this signed-in member sends this group’s finding over this channel (to target only, when named: the Slack channel an admin pressed Send for). The one confirm every sender takes — Slack, Datadog and the weekly email’s switch. A send to a customer’s workspace without one is refused (delivery.gate). A MEMBER’S ACT: only the console, under the service bearer for a signed-in member, may ask — a per-org API token is refused, whatever its scope. Path parameters: orgtag Body fields the handler or its helper reads: channel, group, member, target Response fields written in the handler: confirm, expires_in, org, tier This call changes state in the org.

PUT /v0/orgs/{orgtag}/delivery/{channel}

PUT /v0/orgs/{org}/delivery/{channel} with {on, target?, by?}: turn one channel on or off. Who and when are recorded. A channel whose state is not ready cannot be turned on, and Slack needs a channel id (C…); turning off is always allowed. Answers the channel’s row. Path parameters: orgtag, channel Body fields the handler or its helper reads: by, on, target Response fields written in the handler: channel, org, tier This call changes state in the org.

GET /v0/orgs/{orgtag}/delivery/{channel}/preview

GET /v0/orgs/{org}/delivery/{channel}/preview: the current finding as that channel would carry it — a dry run: nothing is sent, nothing is logged. The finding is always the org’s own: its registered compare by id, or on canary-bravo the stand-in bug compare, labelled “example: invented data” in every rendering; any other org previews nothing yet. Rendered by the channel’s OWN renderer on the inputs its sender reads: Slack’s blocks, the PR comment’s body, Datadog’s event, the weekly email; the download is L4’s file, which the console renders. Path parameters: orgtag, channel Response fields written in the handler: channel, finding, org, preview, tier, why

POST /v0/orgs/{orgtag}/delivery/opens

POST /v0/orgs/{org}/delivery/opens with {group, via, member?}: count one open. Idempotent per member, day and channel — a repeat answers counted: false and writes nothing. member is the signed-in reader’s address, kept only as a hash; absent, the open is anonymous. Path parameters: orgtag Body fields the handler or its helper reads: group, member, via Response fields written in the handler: org This call changes state in the org.

GET /v0/orgs/{orgtag}/delivery/opens

GET /v0/orgs/{org}/delivery/opens?group=: the org’s opens per channel, for one finding or all — line is “opened from Slack 3 · PR 1 · …”. Counts only; never who. Path parameters: orgtag Query parameters the handler or its helper reads: group Response fields written in the helper the handler answers through: anonymous, by_via, group, line, members, opens, org, tier

GET /v0/orgs/{orgtag}/spend

GET /v0/orgs/{org}/spend — today’s budget and what is spent against it, where the budget comes from (the org’s own setting, the env var by name, or the default), the ledger by day for 30 days and by job (kind, started, dollars when priced, who or what asked: a person, a schedule, the pass), and what the budget or a person holds back, each with its estimate and its sentence. A kept read, cut to today here. Path parameters: orgtag Response: JSON: a stored record or a helper’s result, answered as it is, so its keys are not written in the source and none are listed.

PUT /v0/orgs/{orgtag}/budget

PUT /v0/orgs/{org}/budget with {usd_per_day} — the daily budget the after-ingest pass applies within, for this org; null clears it and the env var (by name), else the default, answers again. Kept on the org’s record with who set it; the next pass reads it — one is queued now, so what waited on the old budget is ruled on the new one. Path parameters: orgtag Body fields the handler or its helper reads: usd_per_day Response fields written in the handler: budget, cleared This call changes state in the org.

GET /v0/orgs/{orgtag}/judge

GET /v0/orgs/{org}/judge — the model the org’s LLM-judged checks are decided by, and where it comes from (org, or default: the graders’ own pin); each judged scorer’s model and source (scorer, org, default); the stored overrides with who set them; and the exact model strings an admin may choose — the agents’ allow-list, narrowed to the provider the judge calls. A read of the org’s record; no model call. Path parameters: orgtag Response fields written in the handler: judge, org

PUT /v0/orgs/{orgtag}/judge

PUT /v0/orgs/{org}/judge with {model} — the model this org’s judged checks ask from the next run on; null returns them to the graders’ pin. With {scorer, model}, that one judged scorer’s own model; null returns it to the org’s. Exact strings from the list GET …/judge answers, else 400 naming the list. Kept on the org’s record with who set it. admin: a model choice changes what every later verdict is decided by, and what the exported judges ask the customer’s own Datadog to run. Path parameters: orgtag Body fields the handler or its helper reads: model, scorer Response fields written in the handler: cleared, judge, org This call changes state in the org.

GET /v0/orgs/{orgtag}/confidence

GET /v0/orgs/{org}/confidence — the thresholds the compare’s confidence is banded by (low, high), whether they are the org’s or the defaults (20 and 90), who set them, the bands in words and the formula. A read of the org’s record; no model call. Path parameters: orgtag Response fields written in the handler: confidence, org

PUT /v0/orgs/{orgtag}/confidence

PUT /v0/orgs/{org}/confidence with {low, high} — whole numbers from 0 to 100, low below high; both null returns the org to 20 and 90. Kept on the org’s record with who set them. admin: the bands every member’s PR report reads change with it. Path parameters: orgtag Body fields the handler or its helper reads: high, low Response fields written in the handler: cleared, confidence, org This call changes state in the org.

GET /v0/orgs/{orgtag}/version-labels

GET /v0/orgs/{org}/version-labels — {version: label} for every version this org has named. A read of the org record; no model call. Path parameters: orgtag Response fields written in the handler: labels, main_label, org, tier

PUT /v0/orgs/{orgtag}/version-labels

PUT /v0/orgs/{org}/version-labels with {version, label} — the version string a run group carries (its agent version or a surface version) and the team’s name for it, up to 40 characters; a null label clears it. Naming one version main takes main off any other. Kept on the org record with who named it. push: it spends nothing and is undone by naming it again. Path parameters: orgtag Body fields the handler or its helper reads: label, version Response fields written in the handler: cleared, label, labels, org, tier, version This call changes state in the org.

GET /v0/orgs/{orgtag}/slack

The org’s Slack install: names and ids, never a token. Path parameters: orgtag Response fields written in the handler: configured, events_path, install, oauth, org, signing_secret

POST /v0/orgs/{orgtag}/slack

{team_id, team_name?, by, bot_token?} — connect the org’s Slack workspace. bot_token is the token VALUE from the app’s install page, written to this workspace’s secret store under the org’s name and never kept anywhere else; without it the install names the deployment’s LITMUS_SLACK_BOT_TOKEN, which answers for one org only. Reconnecting overwrites; the response names where the token lives, never the value. Path parameters: orgtag Body fields the handler or its helper reads: bot_token Response fields written in the handler: install, org This call changes state in the org.

DELETE /v0/orgs/{orgtag}/slack

Disconnect: the install goes, and a token this workspace stored for it is deleted from the secret store. The notes it wrote stay. Path parameters: orgtag Response fields written in the handler: deleted, org This call changes state in the org.

POST /v0/orgs/{orgtag}/slack/oauth

{code, redirect_uri, by} — finish Add to Slack. The console’s callback verified its signed state and the admin; this exchanges Slack’s code with the app’s client id and secret (read here by env var NAME, never sent to the console), writes the bot token into this workspace’s secret store under the org’s name, and records the install — the same record the operator’s POST …/slack writes. One Slack workspace answers for one org: a team connected elsewhere is refused with that org named, and the token Slack just minted is not kept. Path parameters: orgtag Body fields the handler or its helper reads: by, code, redirect_uri Response fields written in the handler: install, org This call changes state in the org.

GET /v0/orgs/{orgtag}/members

No description: the handler has no docstring, and nothing here is inferred. Path parameters: orgtag Response fields written in the handler: members

POST /v0/orgs/{orgtag}/members

No description: the handler has no docstring, and nothing here is inferred. Path parameters: orgtag Body fields the handler or its helper reads: added_by, email, email_opt_out, name, role, title Response: JSON: a stored record or a helper’s result, answered as it is, so its keys are not written in the source and none are listed. This call changes state in the org.

PATCH /v0/members/{mid}

No description: the handler has no docstring, and nothing here is inferred. Path parameters: mid Body fields the handler or its helper reads: email_opt_out, name, role, title Response: JSON: a stored record or a helper’s result, answered as it is, so its keys are not written in the source and none are listed. This call changes state in the org.

DELETE /v0/members/{mid}

No description: the handler has no docstring, and nothing here is inferred. Path parameters: mid Response fields written in the handler: deleted This call changes state in the org.

GET /v0/whoami

What the presented credential is. No secrets: an org token learns its org and scope, the service bearer learns it is global. Response fields written in the handler: kind, name, org, scope

GET /v0/orgs

GET /v0/orgs — the orgs this workspace holds, [{org, surfaces, created_at}]. Response fields written in the handler: orgs

GET /v0/orgs/{orgtag}/purge

What deleting this org would remove, without removing it. Path parameters: orgtag Response fields written in the helper the handler answers through: evidence_sidecars, ids, jobs_note, ontology_graph, org, records, total

GET /v0/orgs/{orgtag}/status

GET /v0/orgs/{org}/status[?format=md][&names=1]. Path parameters: orgtag Query parameters the handler or its helper reads: format, names Response: A file, not JSON: text/markdown.

DELETE /v0/orgs/{orgtag}

Delete every trace of an org from this workspace. Irreversible. Path parameters: orgtag Query parameters the handler or its helper reads: confirm Response: JSON: a stored record or a helper’s result, answered as it is, so its keys are not written in the source and none are listed. This call changes state in the org.

POST /v0/orgs/{orgtag}/rename

POST /v0/orgs/{org}/rename {to} — every record the org owns moves to the tag to, as one journaled move. Path parameters: orgtag Body fields the handler or its helper reads: to Response fields written in the handler: error This call changes state in the org.

GET /v0/orgs/{orgtag}/tokens

The org’s tokens: id, name, scope, prefix, created_by, created_at, expires_at, last_used_at, revoked_at. Never the token, never the hash — the record holds only the hash, and the listing drops that too. Path parameters: orgtag Response fields written in the handler: tokens

POST /v0/orgs/{orgtag}/tokens

Mint a token for the org: name (what will hold it), scope in read|push|admin, and optionally expires_in_days or expires_at (unix). created_by is the console’s signed-in email; an admin token minting a child is recorded as token:<its name>. The response carries the raw token — the only time it is ever shown. Path parameters: orgtag Body fields the handler or its helper reads: created_by, expires_at, expires_in_days, name, scope Response fields written in the handler: note, token This call changes state in the org.

DELETE /v0/orgs/{orgtag}/tokens/{tid}

Revoke one token. Idempotent; the next request holding it gets a 401 that names the token and says it was revoked. A token id from another org is 404, not 403 — its existence is not this org’s to learn. Path parameters: orgtag, tid Response: JSON: a stored record or a helper’s result, answered as it is, so its keys are not written in the source and none are listed. This call changes state in the org.