Documentation menu

API reference

14 operations in org. Raw spec: openapi.json.

GET/api/v1/org/exports

GET /api/org/exports — the org-export ledger read model (0089): newest-first list over the exports the org has created so /settings/export grows its list/archive surface over real history.

Parameters

NameInTypeRequiredDescription
archivedquery—NoFilter by archive state; absent returns all rows.
limitqueryintegerNo
offsetqueryintegerNo

Responses

StatusDescription
200

Security: bearer

POST/api/v1/org/exports

POST /api/org/exports — builds the versioned bundle, streams it into the ObjectStore, and returns the signed download link.

Responses

StatusDescription
200

Security: bearer

PATCH/api/v1/org/exports/{export_id}

PATCH /api/org/exports/{export_id} — archives (or restores) ONE ledger row; a pure read-model toggle over the row, content untouched.

Parameters

NameInTypeRequiredDescription
export_idpathstringYes

Request body

ExportArchiveUpdate

Responses

StatusDescription
200
404export not in this org's ledger

Security: bearer

GET/api/v1/org/exports/{org_id}/{export_id}/download

GET /api/org/exports/{org_id}/{export_id}/download — streams the stored bundle. Authenticated by the signed link alone (no JWT): an expired or forged token is an unauthorized request, indistinguishable between the two. The org id is IN the path (and inside the signature) so a token authorizes exactly one (org, export, expiry) triple.

Parameters

NameInTypeRequiredDescription
org_idpathstringYes
export_idpathstringYes

Responses

StatusDescription
200
GET/api/v1/org/manifest

GET /api/org/manifest — the org's customization manifest.

Owner/admin gated (policy §5: the manifest is an org-level administrative artifact; technicians and dispatchers have no business reading the full customization inventory, e.g. webhook URLs).

Responses

StatusDescription
200

Security: bearer

GET/api/v1/orgs/{org_id}/custom-domain

`GET /api/v1/orgs/{org_id}/custom-domain` — current state + verification status + provider-plugin availability.

Parameters

NameInTypeRequiredDescription
org_idpathstringYesthe org; must be the caller's own org

Responses

StatusDescription
200
401not authenticated
403service account without org_custom_domain:read
404no such org for this caller

Security: bearer

POST/api/v1/orgs/{org_id}/custom-domain

`POST /api/v1/orgs/{org_id}/custom-domain` — claim a domain.

Parameters

NameInTypeRequiredDescription
org_idpathstringYesthe org; must be the caller's own org

Request body

SetCustomDomainRequest

Responses

StatusDescription
200
400invalid domain
401not authenticated
403not an admin / missing org_custom_domain:manage
404no such org for this caller
409domain already claimed by another workspace

Security: bearer

DELETE/api/v1/orgs/{org_id}/custom-domain

`DELETE /api/v1/orgs/{org_id}/custom-domain` — clear the domain.

Parameters

NameInTypeRequiredDescription
org_idpathstringYesthe org; must be the caller's own org

Responses

StatusDescription
204domain cleared
401not authenticated
403not an admin / missing org_custom_domain:manage
404no such org for this caller

Security: bearer

POST/api/v1/orgs/{org_id}/custom-domain/verify

`POST /api/v1/orgs/{org_id}/custom-domain/verify` — run the generic DNS verification (the private build tracker A8 (C)). The TXT token is the authority; the A/CNAME leg is plausibility only.

Parameters

NameInTypeRequiredDescription
org_idpathstringYesthe org; must be the caller's own org

Responses

StatusDescription
200
401not authenticated
403not an admin / missing org_custom_domain:manage
404no such org for this caller
409no custom domain is set

Security: bearer

GET/api/v1/orgs/{org_id}/quotas

GET /api/v1/orgs/{org_id}/quotas — usage beside configured limits.

Informational by construction: a percentage here is a measurement, and nothing in the core reads this endpoint to limit anything. `limits` is a real configuration read — an org that has configured none reports `false`, because a default limit is a fake gate.

Parameters

NameInTypeRequiredDescription
org_idpathstringYesthe org to report on; must be the caller's own org

Responses

StatusDescription
200
401not authenticated
403service account without org_usage:read
404no such org for this caller

Security: bearer

GET/api/v1/orgs/{org_id}/suspension-status

`GET /api/v1/orgs/{org_id}/suspension-status` — the org's notice state.

Parameters

NameInTypeRequiredDescription
org_idpathstringYesthe org; must be the caller's own org

Responses

StatusDescription
200
401not authenticated
403service account without org_suspension:read
404no such org for this caller

Security: bearer

PATCH/api/v1/orgs/{org_id}/suspension-status

`PATCH /api/v1/orgs/{org_id}/suspension-status` — set or clear the flag (`admin:edit`). Idempotent; emits `org.suspension_changed` + an audit row.

Parameters

NameInTypeRequiredDescription
org_idpathstringYesthe org; must be the caller's own org

Request body

SetSuspensionRequest

Responses

StatusDescription
200
401not authenticated
403not an admin (no admin:edit)
404no such org for this caller
422unknown reason, or a missing one when suspending

Security: bearer

GET/api/v1/orgs/{org_id}/usage

GET /api/v1/orgs/{org_id}/usage — the org's current usage counts.

`refreshed_at` is when the numbers were computed; a consumer that needs fresh numbers reads the row's own timestamp instead of assuming. `unavailable` names every metric this build cannot compute honestly, with the reason — it is a real, renderable list, not a placeholder.

Parameters

NameInTypeRequiredDescription
org_idpathstringYesthe org to report on; must be the caller's own org

Responses

StatusDescription
200
401not authenticated
403service account without org_usage:read
404no such org for this caller

Security: bearer