Public API — Reference (generated)
<!-- GENERATED FILE — do not hand-edit. Regenerate: `npm run docs:public-api`. -->For the versioning policy (what v1 guarantees, what forces a v2, the v1
deprecation window, auth, error shapes, pagination — all independently
verified prose), see public-api-versioning.md.
For an interactive, always-current copy of this same information, see the
live docs portal: /api/v1/reference / /api/v2/reference (ReDoc),
/api/v1/docs / /api/v2/docs (Swagger UI), /api/v1/docs-json /
/api/v2/docs-json (raw OpenAPI 3.0). All paths below are relative to
the API base URL (e.g. https://app.cmdash.net/api).
For the exact shape of a failed request and every fixed error value the
API can return, see error-catalogue.md. For safe
request retries — including a curl example against this API — see the
public-API section of idempotency.md.
v1 Endpoints
16 endpoints across 5 resource groups. v1 is deprecated
but unchanged — every response below still carries the exact shape it
always has, including the two known 200 { error: ... } cases (see
public-api-versioning.md's "Error shapes" section).
| Method | Path | Permission scope | Params | Summary |
|---|---|---|---|---|
| GET | /v1/compliance/frameworks | compliance:read | — | List compliance frameworks with progress |
| GET | /v1/compliance/frameworks/:slug/controls | compliance:read | slug | Get control statuses for a framework |
| GET | /v1/compliance/progress | compliance:read | — | Get compliance progress across all frameworks |
| POST | /v1/gate/evaluate | gate:read | — | Evaluate the posture-as-code CI gate |
| GET | /v1/gate/policy | gate:read | — | Get the effective posture-gate policy (defaults if never configured) |
| GET | /v1/integrations | integrations:read | — | List connected integrations |
| GET | /v1/integrations/:id/health | integrations:read | id | Get integration sync status and health |
| GET | /v1/posture/history | posture:read | days | Get posture score history |
| GET | /v1/posture/latest | posture:read | — | Get latest posture score |
| GET | /v1/posture/signals | posture:read | — | Get detailed signal breakdown |
| GET | /v1/risks | risks:read | status, category, minScore, limit, offset | List risks with optional filtering |
| POST | /v1/risks | risks:write | — | Create a new risk |
| PUT | /v1/risks/:id | risks:write | id | Update a risk |
| GET | /v1/risks/:id/controls | risks:read | id | Get linked controls for a risk |
| GET | /v1/risks/:id/loss-exposure | fair:read | id | Get FAIR loss exposure for a single risk |
| GET | /v1/risks/loss-exposure | fair:read | — | Get FAIR loss-exposure summary (ALE + percentiles) |
v2 Endpoints
45 endpoints across 15 resource groups. Every v1 route has a
v2 counterpart at the same sub-path; v2 additionally fixes the two
200 { error: ... } cases to a real 404, and adds new resources
(webhooks, reports, audit-logs) that have no v1 equivalent.
| Method | Path | Permission scope | Params | Summary |
|---|---|---|---|---|
| GET | /v2/assets | assets:read | assetType, criticality, limit, offset | List assets |
| GET | /v2/assets/:id | assets:read | id | Get one asset by id |
| GET | /v2/audit-logs | audit-logs:read | page, limit, action, from, to | List audit logs with pagination and optional filters |
| GET | /v2/audit-logs/export | audit-logs:read | format, from, to, action | Export audit logs as CSV or JSON for external auditors |
| GET | /v2/collector/definitions | integrations:read | connectorId | Connector definitions this tenant has marked COLLECTOR-mode. Never includes credentials — |
| POST | /v2/collector/keys | observations:write | — | Register the collector’s Ed25519 public key with a one-time token and a proof of possession. The private key never leaves the collector. |
| POST | /v2/collector/keys/rotate | observations:write | — | Replace the collector’s key; the rotation is signed by BOTH the registered key and the new one. |
| POST | /v2/collector/push | observations:write | — | Push results collected inside your own network. Requires a valid X-CMDash-Collector-Signature. |
| GET | /v2/compliance/frameworks | compliance:read | — | List compliance frameworks with progress |
| GET | /v2/compliance/frameworks/:slug/controls | compliance:read | slug | Get control statuses for a framework |
| GET | /v2/compliance/progress | compliance:read | — | Get compliance progress across all frameworks |
| GET | /v2/evidence | evidence:read | status, collectionMethod, frameworkSlug, controlId, limit, offset | List evidence items |
| POST | /v2/evidence | evidence:write | — | File evidence against controls from your own tooling |
| GET | /v2/evidence/:id | evidence:read | id | Get one evidence by id |
| POST | /v2/gate/evaluate | gate:read | — | Evaluate the posture-as-code CI gate |
| GET | /v2/gate/policy | gate:read | — | Get the effective gate policy (defaults if never configured) |
| GET | /v2/incidents | incidents:read | status, severity, limit, offset | List incidents |
| GET | /v2/incidents/:id | incidents:read | id | Get one incident by id |
| GET | /v2/integrations | integrations:read | — | List connected integrations |
| GET | /v2/integrations/:id/health | integrations:read | id | Get integration sync status and health |
| POST | /v2/integrations/:id/sync | integrations:write | id | Trigger an on-demand sync for a connection |
| POST | /v2/observations | observations:write | — | Push maturity observations from your own tooling |
| GET | /v2/policies | policies:read | status, category, limit, offset | List policies |
| GET | /v2/policies/:id | policies:read | id | Get one policy by id |
| GET | /v2/posture/history | posture:read | days | Get posture score history |
| GET | /v2/posture/latest | posture:read | — | Get latest posture score |
| GET | /v2/posture/signals | posture:read | — | Get detailed signal breakdown |
| GET | /v2/reports | reports:read | limit | List generated reports |
| GET | /v2/reports/:id | reports:read | id | Get a generated report status and content |
| POST | /v2/reports/generate | reports:generate | — | Generate a report from a template or ad-hoc sections |
| GET | /v2/risks | risks:read | status, category, minScore, limit, offset | List risks with optional filtering |
| POST | /v2/risks | risks:write | — | Create a new risk |
| PUT | /v2/risks/:id | risks:write | id | Update a risk |
| GET | /v2/risks/:id/controls | risks:read | id | Get linked controls for a risk |
| GET | /v2/risks/:id/loss-exposure | fair:read | id | Get FAIR loss exposure for a single risk |
| GET | /v2/risks/loss-exposure | fair:read | — | Get FAIR loss-exposure summary (ALE + percentiles) |
| GET | /v2/vendors | vendors:read | status, tier, criticality, limit, offset | List vendors |
| GET | /v2/vendors/:id | vendors:read | id | Get one vendor by id |
| GET | /v2/webhooks | webhooks:read | — | List all webhook registrations for the tenant |
| POST | /v2/webhooks | webhooks:write | — | Register a new webhook endpoint |
| DELETE | /v2/webhooks/:id | webhooks:write | id | Delete a webhook registration |
| PUT | /v2/webhooks/:id | webhooks:write | id | Update a webhook registration |
| GET | /v2/webhooks/:id/logs | webhooks:read | id, limit | Get delivery logs for a webhook |
| POST | /v2/webhooks/:id/rotate-secret | webhooks:write | id, overlapHours | Rotate the webhook HMAC signing secret |
| POST | /v2/webhooks/:id/test | webhooks:write | id | Send a single synthetic test event through the real delivery path |
Permission scopes
Every scope in ApiKeyService's VALID_PERMISSIONS whitelist — which is
NOT versioned, a key's scopes work against whichever version's routes it
calls — and whether a v1 route and/or a v2 route actually checks it
today. A key may be issued with a scope neither version enforces yet;
see public-api-versioning.md for what that means and for the one scope
(compliance:write) that was removed from this whitelist entirely rather
than carried into v2 unenforced.
| Scope | Enforced by v1 | Enforced by v2 |
|---|---|---|
posture:read | Yes | Yes |
risks:read | Yes | Yes |
risks:write | Yes | Yes |
compliance:read | Yes | Yes |
integrations:read | Yes | Yes |
integrations:write | No | Yes |
reports:read | No | Yes |
reports:generate | No | Yes |
webhooks:read | No | Yes |
webhooks:write | No | Yes |
audit-logs:read | No | Yes |
fair:read | Yes | Yes |
gate:read | Yes | Yes |
evidence:write | No | Yes |
observations:write | No | Yes |
policies:read | No | Yes |
vendors:read | No | Yes |
evidence:read | No | Yes |
assets:read | No | Yes |
incidents:read | No | Yes |
API key lifetime
Default expiry: 90 days. Maximum expiry: 365 days (enforced at creation and rotation).
Re-authentication for key management
An API key is a bearer credential that outlives the session that minted it, so the routes that mint, rotate or revoke one are gated on a FRESH credential — a stolen access token is not enough on its own.
| Method | Path | Gated action |
|---|---|---|
| POST | /api-keys | create an API key |
| DELETE | /api-keys/:id | revoke this API key |
| POST | /api-keys/:id/rotate | rotate this API key |
Call POST /auth/reauth with { "password": "…" } (or { "mfaCode": "123456" } on an account with MFA) on the authenticated session. It returns a short-lived proof; replay it in the X-Fresh-Auth header on the gated call. The proof is valid for 10 minutes by default (FRESH_AUTH_TTL_MINUTES), is bound to the user who obtained it, and grants nothing on its own.
Without a valid proof the call returns 403 with error: "FRESH_AUTH_REQUIRED" (repeated in details.code). The session is still valid — refresh nothing and sign nobody out; obtain a proof and retry once. See error-catalogue.md.
Listing keys and reading a key's rate-limit usage are NOT gated: a read changes no credential.
Rate limits
Per-API-key, Redis-backed, fixed 60-minute window, resolved from the calling tenant's org tier. Applies identically to v1 and v2 (the limiter keys on the API key, not the path version).
| Tier | Requests / window |
|---|---|
| STARTER | 500 |
| ESSENTIALS | 2,000 |
| COMMAND | 10,000 |
| ENTERPRISE | 20,000 |
| (tenant/tier unresolvable) | 1,000 (flat fallback) |
Plans without Public API access are not listed: no API key can be minted on them.