System-level management of organizations and the users that belong to them.
Common responses
These responses apply across endpoints in this section unless an endpoint documents an additional response.
Status
Meaning
Body
200
Request succeeded.
Endpoint response object.
201
Resource created.
Created resource object.
400
Invalid request.
Error envelope.
401
Missing or invalid bearer token.
Error envelope.
404
Resource not found or not visible to the current organization.
Error envelope.
Organizations
List organizations
List organizations in the system, paginated. Soft-deleted organizations are hidden by default; pass `isDeleted=true` to fetch only tombstoned orgs (e.g. for a Deleted tab) or `isDeleted=false` to be explicit about the live-only view. Use `search` for a case-insensitive substring match on name, and `isSystem` to filter system-orgs vs tenant-orgs. Each row is enriched with the joined plan name, total user count, and tasks created in the last 30 days.
GET/v1/admin/organizations
Query parameters
Name
Type
Required
Description
search
string
Optional
Case-insensitive substring match on organization name.
isSystem
boolean
Optional
When set, returns only system orgs (true) or only tenant orgs (false). Omit to return both.
isDeleted
boolean
Optional
Filters by soft-delete state. `true` returns only tombstoned organizations (Deleted tab); `false` returns only live organizations (Active tab, same as the default); omit to use the live-only default.
cursor
string
Optional
Opaque pagination cursor returned in next_cursor of the previous response. Omit to start at the beginning.
limit
number
Optional
Maximum number of items to return. Default 20, max 100.
Return a single organization by ID. Soft-deleted organizations are still returned by this endpoint (with `deletedAt` populated) so operators can inspect tombstones. Returns 404 only when the ID does not exist at all.
Create a new organization. The new org is auto-subscribed to the "free" plan; use POST /admin/organizations/:id/subscription/change-plan to move it to a paid plan. The new org has no users — create at least one admin via `POST /admin/organizations/:id/users` before anyone can sign in. The `isSystem` flag is intentionally NOT exposed: system organizations are assigned at seed time and cannot be created through the API.
POST/v1/admin/organizations
Request body
Name
Type
Required
Description
name
string
Required
Organization name. Must be unique across the system. 1–255 chars.
industry
string
Optional
Free-form industry label (e.g. "saas", "fintech"). Maximum 255 chars. Pass null to clear.
primaryLanguage
string
Optional
BCP-47 language tag. Default "en". Maximum 32 chars.
primaryTimezone
string
Optional
IANA timezone identifier (e.g. "America/New_York"). Default "UTC". Maximum 64 chars.
Patch an organization's editable fields. The request body is strict — passing an unknown field (including `isSystem`, `isSuspended`, or `planId`) returns 400. Toggle suspension via the dedicated suspend/unsuspend routes. Change the plan via POST /admin/organizations/:id/subscription/change-plan.
PATCH/v1/admin/organizations/:id
Path parameters
Name
Type
Required
Description
id
string
Required
The organization's UUID.
Request body
Name
Type
Required
Description
name
string
Optional
New organization name. Must remain unique. 1–255 chars.
industry
string
Optional
Free-form industry label. Pass null to clear.
primaryLanguage
string
Optional
BCP-47 language tag.
primaryTimezone
string
Optional
IANA timezone identifier.
policyOverrides
object
Optional
Free-form JSON object of policy override key/values. Replaces the existing object wholesale.
Mark an organization as suspended. Suspended orgs are blocked from acting on the platform (the runtime auth/policy layer rejects their traffic). Idempotency is not assumed: calling suspend on an already-suspended org returns 409 rather than silently succeeding, so operators see the state they expect. The request body is ignored.
POST/v1/admin/organizations/:id/suspend
Path parameters
Name
Type
Required
Description
id
string
Required
The organization's UUID.
Example requestbash
curl -X POST https://api.cortex.cognit-dx.com/v1/admin/organizations/f1ba15e0-ebe8-4187-afe6-03ccb25b8815/suspend \
-H "Authorization: Bearer $CORTEX_TOKEN"
Response codes
Status
Meaning
Body
404
Organization not found.
`{ error, code: 'not_found' }`
409
Either the org is soft-deleted (`organization_deleted`) or it is already suspended (`already_suspended`).
`{ error, code }`
403
Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.
Reverse a prior suspension. Calling on a non-suspended org returns 409 (`not_suspended`). Calling on a soft-deleted org returns 409 (`organization_deleted`) — restore the org first.
POST/v1/admin/organizations/:id/unsuspend
Path parameters
Name
Type
Required
Description
id
string
Required
The organization's UUID.
Example requestbash
curl -X POST https://api.cortex.cognit-dx.com/v1/admin/organizations/f1ba15e0-ebe8-4187-afe6-03ccb25b8815/unsuspend \
-H "Authorization: Bearer $CORTEX_TOKEN"
Response codes
Status
Meaning
Body
404
Organization not found.
`{ error, code: 'not_found' }`
409
Either the org is soft-deleted (`organization_deleted`) or it is not currently suspended (`not_suspended`).
`{ error, code }`
403
Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.
Soft-delete an organization. Sets `deletedAt` to the current timestamp and forces `suspended` to true so the org immediately stops serving traffic. The org row remains in the database (hidden from default list responses) and can be brought back with `POST /restore`. Calling delete on an already-deleted org returns 409 (`already_deleted`).
Reverse a prior soft-delete by clearing `deletedAt`. Does NOT auto-unsuspend: suspension is intentionally orthogonal to soft-delete, so an operator may restore a tombstoned org while keeping it suspended pending review. Calling restore on a non-deleted org returns 409 (`not_deleted`).
POST/v1/admin/organizations/:id/restore
Path parameters
Name
Type
Required
Description
id
string
Required
The organization's UUID.
Example requestbash
curl -X POST https://api.cortex.cognit-dx.com/v1/admin/organizations/f1ba15e0-ebe8-4187-afe6-03ccb25b8815/restore \
-H "Authorization: Bearer $CORTEX_TOKEN"
Response codes
Status
Meaning
Body
404
Organization not found.
`{ error, code: 'not_found' }`
409
Organization is not currently deleted.
`{ error, code: 'not_deleted' }`
403
Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.
List every user belonging to an organization, sorted by email ascending. Each row is enriched with the joined organization name and `is_system` flag, plus `console_role_id` (the assigned console role, null when none). Pagination is not applied — typical org sizes don't warrant it.
Provision a new user inside an organization. The server generates a strong one-time password and returns it in the response as plaintext — it is never persisted in plaintext and never returned again. Capture this value at the call site and share it with the user out-of-band (email, secure channel). The new user can change it after first sign-in.
POST/v1/admin/organizations/:id/users
Path parameters
Name
Type
Required
Description
id
string
Required
The organization's UUID.
Request body
Name
Type
Required
Description
firstName
string
Required
Given name. 1–255 chars.
lastName
string
Required
Family name. 1–255 chars.
displayName
string
Optional
How the user should be addressed in UIs. Defaults to `"{firstName} {lastName}"` when omitted.
email
string
Required
Login email. Lowercased and trimmed server-side. Must be globally unique across all orgs.
role
string
Optional
One of `admin` or `member`. Default `member`.
isDeveloper
boolean
Optional
Grant developer access for developer-gated tools and APIs. Default `false`.
Fetch a single user, asserting they belong to the named organization. If the user exists but belongs to a different org, the response is 404 (same as if the user didn't exist) so cross-org probes can't enumerate IDs. Returns the enriched user row.
Update a user's display fields, role, developer-access flag, or console role. Two guards apply: (1) you cannot demote yourself from `admin` — that has to come from another admin; (2) you cannot demote the last active admin of the organization (the org would be left without anyone able to manage it). Both violations return 409. `consoleRoleId` assigns (or, passed `null`, clears) the user's console role — see Console roles in Authentication; it's accepted only for users of the system organization and returns 400 `validation_error` otherwise. A system-organization member must always keep a console role: a patch that would leave a non-admin without one (clearing the role, or demoting an admin who has none) returns 400 — suspend the user to revoke console access instead.
PATCH/v1/admin/organizations/:id/users/:userId
Path parameters
Name
Type
Required
Description
id
string
Required
The organization's UUID.
userId
string
Required
The user's UUID.
Request body
Name
Type
Required
Description
firstName
string
Optional
Given name. 1–255 chars.
lastName
string
Optional
Family name. 1–255 chars.
displayName
string | null
Optional
How the user is addressed in UIs. Pass `null` to reset it to the `first_name + last_name` default.
role
string
Optional
One of `admin` or `member`.
isDeveloper
boolean
Optional
Grant (`true`) or revoke (`false`) developer access.
consoleRoleId
string | null
Optional
UUID of a console role to assign, or `null` to clear it (clearing is rejected for system-org members — they must always hold a role). System-organization users only — see GET /v1/admin/console-roles for the available roles.
Block a user from signing in or acting on the platform. Two guards apply: (1) you cannot suspend yourself; (2) you cannot suspend the last active admin of the organization. Both violations return 409. The body is ignored.
Set a user's password or ask the server to generate a strong temporary password. When the request omits `password`, the generated plaintext password is returned exactly once. When a password is supplied, the response does not echo it back.
Soft-delete a user from an organization. Deleted users are hidden from normal user lists and sign-in lookup paths, but the row remains in the database for auditability. Two guards apply: you cannot delete yourself, and you cannot delete the last active admin of the organization.
Cannot delete your own user, or cannot delete the last active admin.
`{ error }`
403
Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.
`{ error, code, request_id }`
Service accounts
List service accounts
List all service accounts that belong to the organization. Returns an `{ items }` envelope. Useful for auditing which non-human principals have API keys in a given tenant.
Create a service account in the target organization. API keys issued to this account inherit its role and permissions. Privileged flags (`can_access_console`, `can_mint_cross_org`) are hardcoded `false` regardless of the request body. Returns 409 `duplicate_name` if a service account with the same name already exists in the org.
POST/v1/admin/organizations/:id/service-accounts
Path parameters
Name
Type
Required
Description
id
string
Required
The id value from the endpoint path.
Request body
Name
Type
Required
Description
name
string
Required
Unique name within the organization (max 120 characters).
Update the name, description, role, or suspension state of a service account. All fields are optional. Privileged flags (`can_access_console`, `can_mint_cross_org`) cannot be changed via this endpoint. Returns 409 `duplicate_name` if renaming to a name already in use. Returns 404 if not found.
Permanently delete a service account. Returns 409 `has_live_keys` if the account still owns non-revoked API keys — revoke the keys first. Returns 404 if not found.
Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.
`{ error, code, request_id }`
204 No Contenttext
Departments
List departments
List all departments in the organization, ordered by name. The `parent_department_id` field enables a tree structure — `null` denotes a top-level department.
List every console role with its granted sections and current user count. Console roles let a non-admin, system-organization user reach specific platform sections without the blanket access `users.role === "admin"` grants — assign one with the `consoleRoleId` field on Update user. These management routes are themselves gated on the `access` section. See Console roles in Authentication for how sections gate access.
Create a new console role with a name and a set of granted sections. Assign the role to a system-organization user via the `consoleRoleId` field on Update user, or via the dedicated System users endpoints below.
POST/v1/admin/console-roles
Request body
Name
Type
Required
Description
name
string
Required
Unique role name, case-insensitive.
sections
array
Required
Sections to grant (string[], at least one — a role with no sections is rejected with 400). Any of: platform, organizations, sales, operations, ai-platform, billing, access.
Rename a console role and/or replace its granted sections. `sections`, when sent, replaces the full set atomically — it is not merged with the existing sections.
PATCH/v1/admin/console-roles/:id
Path parameters
Name
Type
Required
Description
id
string
Required
The id value from the endpoint path.
Request body
Name
Type
Required
Description
name
string
Optional
New role name, case-insensitive-unique.
sections
array
Optional
Full replacement set of sections (string[], at least one — emptying a role is rejected with 400). Any of: platform, organizations, sales, operations, ai-platform, billing, access.
Delete a console role. Any user currently assigned the role is automatically unassigned (`consoleRoleId` is set to null via the foreign key's `ON DELETE SET NULL`) — no user is deleted or suspended as a side effect.
Admin access required — caller lacks the system admin role and holds no console role mapped to the `access` section.
`{ error, code: 'admin_required', request_id }`
System users
List system users
List the caller's own (system) organization's users along with their console-role assignment. Gated on the `access` section; the caller's organization is resolved server-side from the credential and verified to be the system organization — a non-system-org caller gets 403, same as any other console-permission denial.
`{ data }` — `console_role_id`/`console_role` are both null when the user holds no console role.
401
Missing or invalid credential.
`{ error, code, request_id }`
403
Admin access required — caller lacks the system admin role and holds no console role mapped to the `access` section, or the caller's organization is not the system organization.
Create a user in the caller's own (system) organization. A one-time plaintext password is generated and returned exactly once in the response — it is never persisted in plaintext or returned again. Gated on the `access` section and the caller's organization is verified to be the system organization.
POST/v1/admin/system-users
Request body
Name
Type
Required
Description
first_name
string
Required
Given name (1–255 chars).
last_name
string
Required
Family name (1–255 chars).
email
string
Required
Unique email within the organization.
role
string
Optional
Organization role: `admin` or `member` (default `member`). Admins see every console section.
console_role_id
string | null
Optional
Console role to assign at creation. Required when `role` is `member` — a role-less member would face a console with no sections (400 `validation_error` without it). Optional for admins, who see every section regardless. An unknown id returns 400.
Assign or clear a system-org user's console role and/or toggle suspension. Both fields are optional and independent — send only what you want to change. 404s if `:id` does not resolve to an active user of the caller's (system) organization.
PATCH/v1/admin/system-users/:id
Path parameters
Name
Type
Required
Description
id
string
Required
The id value from the endpoint path.
Request body
Name
Type
Required
Description
console_role_id
string | null
Optional
A console role id to assign, or null to clear. Clearing is rejected with 400 for members — they must always hold a console role (suspend the user to revoke access). An unknown id also returns 400.
is_suspended
boolean
Optional
Suspend (`true`) or unsuspend (`false`) the user. Suspending your own account returns 409.
Admin access required — caller lacks the system admin role and holds no console role mapped to the `access` section, or the caller's organization is not the system organization.
Reset a system-org user's password. Omit `password` to have one generated server-side — the plaintext value is returned once in the response body and cannot be retrieved again.
POST/v1/admin/system-users/:id/password
Path parameters
Name
Type
Required
Description
id
string
Required
The id value from the endpoint path.
Request body
Name
Type
Required
Description
password
string
Optional
New plaintext password, minimum 12 characters. Omit to auto-generate one.
`{ password }` — the generated plaintext value, or null when you supplied one.
404
User not found in the caller's organization.
`{ error, request_id }`
401
Missing or invalid credential.
`{ error, code, request_id }`
403
Admin access required — caller lacks the system admin role and holds no console role mapped to the `access` section, or the caller's organization is not the system organization.
`{ error, code: 'admin_required', request_id }`
200 OKjson
{
"password": "aD4!k9Zp2$mQ8vNr"
}
Demo organizations
List demo organizations
List every demo organization, most recently created first. Each row is enriched with the creator's display name, the current admin user's email, the wallet balance, and the user count — everything the Demo Center table needs without a follow-up request.
Atomically provision a full demo tenant: the organization, a `demo`-plan subscription, a $50 prepaid wallet (enforcement on), and one admin user — in a single transaction, so a failure partway through leaves no partial rows. The organization name is suffixed with ` - Demo`; if that suffixed name already exists, returns 409 `duplicate_name` before opening the transaction. `expiresAt` defaults to 14 days out when omitted. The admin's password is generated server-side and returned once, in plaintext — it is never recoverable afterward; use Reset admin password to issue a fresh one.
POST/v1/admin/demo-organizations
Request body
Name
Type
Required
Description
name
string
Required
Prospect/company name, before the ` - Demo` suffix is appended. Max 255 characters.
adminFirstName
string
Required
First name for the generated admin user.
adminLastName
string
Required
Last name for the generated admin user.
adminEmail
string
Required
Email for the generated admin user. Lowercased on save.
expiresAt
string
Optional
ISO 8601 timestamp the demo expires at. Defaults to 14 days from creation.
Return a single demo organization plus every user in it. Returns 404 — never 403 — if the id doesn't exist or belongs to a real (non-demo) tenant; demo routes are simply blind to ordinary organizations.
Push out a demo organization's expiry. Touches only `expiresAt` — suspension state is untouched, the same split as Suspend/Unsuspend on the plain organizations routes. `expiresAt` must be a future timestamp; the body is strict, so an unrecognized field is also rejected. Returns the updated organization row directly — not wrapped in an `organization` key.
Issue a fresh one-time password for a user in a demo organization — the same generated-password flow as Create demo organization. Returns the plaintext password once; it is never recoverable afterward.