CORTEX

Models

AI providers, model categories, and model versions installed in the system.

Common responses

These responses apply across endpoints in this section unless an endpoint documents an additional response.

StatusMeaningBody
200Request succeeded.Endpoint response object.
201Resource created.Created resource object.
400Invalid request.Error envelope.
401Missing or invalid bearer token.Error envelope.
404Resource not found or not visible to the current organization.Error envelope.

AI providers

List AI providers

Return every AI provider configured in the system, sorted by display name ascending. The response is cursor-paginated; follow `next_cursor` while `has_more` is true. Providers are the top of the model hierarchy — a provider owns one or more model categories, which in turn own one or more model versions. Every provider response carries one derived boolean alongside the stored columns: `has_api_key` (an encrypted key is configured — the key itself is never returned). Every registered provider lists its models live from the vendor's own models API (`GET /v1/admin/ai-providers/:id/available-models`); the API key stored on the provider is what authenticates that call, except for Cerebras, whose catalog is public.

GET/v1/admin/ai-providers
Example requestbash
curl https://api.cortex.cognit-dx.com/v1/admin/ai-providers \
  -H "Authorization: Bearer $CORTEX_TOKEN"

Response codes

StatusMeaningBody
401Missing or invalid credential.`{ error, code, request_id }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
200 OKjson
{
  "data": [
    {
      "id": "a8e3f47c-2b9d-4e1a-9c5f-7d6b8e2a1c34",
      "name": "Anthropic",
      "slug": "anthropic",
      "website": "https://anthropic.com",
      "has_api_key": true,
      "created_at": "2026-05-18T10:24:31.000Z",
      "updated_at": "2026-05-18T10:24:31.000Z"
    },
    {
      "id": "5f8c2b14-7e3a-49d8-b6c4-2a1e9f3d7b58",
      "name": "OpenAI",
      "slug": "openai",
      "website": "https://openai.com",
      "has_api_key": true,
      "created_at": "2026-05-18T10:24:31.000Z",
      "updated_at": "2026-05-18T10:24:31.000Z"
    }
  ],
  "total": 0,
  "has_more": false,
  "next_cursor": null
}

Get AI providers catalog

A picker-friendly view of what Cortex can route to **today** — nested provider → families with their **supported capabilities**. Only the four organization-facing capabilities are surfaced: `text`, `image`, `audio`, `embeddings` (the family's other declared modalities such as `video` or `documents` are not surfaced here even when present on the latest version). Families whose latest version has none of these supported capabilities are omitted, and providers with no surviving families are dropped from the response. Use this to power model-picker UIs.

GET/v1/admin/ai-providers/catalog
Example requestbash
curl https://api.cortex.cognit-dx.com/v1/admin/ai-providers/catalog \
  -H "Authorization: Bearer $CORTEX_TOKEN"

Response codes

StatusMeaningBody
401Missing or invalid credential.`{ error, code, request_id }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
200 OKjson
{
  "data": [
    {
      "provider_id": "a8e3f47c-2b9d-4e1a-9c5f-7d6b8e2a1c34",
      "provider_name": "Anthropic",
      "families": [
        {
          "model_id": "d2c5b1a9-4e8f-43d6-b271-5a9c8e3f6d12",
          "family_name": "Claude Sonnet",
          "capabilities": [
            "text",
            "image"
          ]
        }
      ]
    }
  ],
  "has_more": false,
  "next_cursor": null,
  "total": 0
}

Create AI provider

Register a new provider. `slug` is globally unique and is the stable identifier the rest of the system uses (URL paths, logs, audit events). Display `name` can be changed freely later.

POST/v1/admin/ai-providers

Request body

NameTypeRequiredDescription
namestringRequiredDisplay name shown in admin UIs and dashboards. 1–100 chars.
slugstringRequiredLowercase URL-safe identifier matching `^[a-z0-9-]+$`. Must be globally unique. 1–50 chars. Used in logs and audit trails — choose carefully, renames cascade.
websitestringOptionalOptional vendor URL. Max 255 chars. Pass null to clear.
api_keystringOptionalOptional API key used to call the provider. Write-only: stored encrypted at rest and never returned by any endpoint — responses expose only the `has_api_key` boolean. 1–512 chars.
Example requestbash
curl https://api.cortex.cognit-dx.com/v1/admin/ai-providers \
  -H "Authorization: Bearer $CORTEX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Anthropic",
    "slug": "anthropic",
    "website": "https://anthropic.com"
  }'

Response codes

StatusMeaningBody
201Provider created.The new AIProvider row.
409A provider with that slug already exists.`{ error }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
201 Createdjson
{
  "id": "a8e3f47c-2b9d-4e1a-9c5f-7d6b8e2a1c34",
  "name": "Anthropic",
  "slug": "anthropic",
  "website": "https://anthropic.com",
  "has_api_key": true,
  "created_at": "2026-05-18T10:24:31.000Z",
  "updated_at": "2026-05-18T10:24:31.000Z"
}

Get AI provider

Return a single provider by ID. To traverse to the provider's families, call `GET /admin/ai-model-families?providerId=:id`.

GET/v1/admin/ai-providers/:id

Path parameters

NameTypeRequiredDescription
idstringRequiredThe provider's UUID.
Example requestbash
curl https://api.cortex.cognit-dx.com/v1/admin/ai-providers/a8e3f47c-2b9d-4e1a-9c5f-7d6b8e2a1c34 \
  -H "Authorization: Bearer $CORTEX_TOKEN"

Response codes

StatusMeaningBody
404Provider not found.`{ error }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
200 OKjson
{
  "id": "a8e3f47c-2b9d-4e1a-9c5f-7d6b8e2a1c34",
  "name": "Anthropic",
  "slug": "anthropic",
  "website": "https://anthropic.com",
  "has_api_key": true,
  "created_at": "2026-05-18T10:24:31.000Z",
  "updated_at": "2026-05-18T10:24:31.000Z"
}

Update AI provider

Patch a provider's editable fields. Slug renames are allowed but trigger a uniqueness check against every other provider — 409 on collision.

PATCH/v1/admin/ai-providers/:id

Path parameters

NameTypeRequiredDescription
idstringRequiredThe provider's UUID.

Request body

NameTypeRequiredDescription
namestringOptionalNew display name. 1–100 chars.
slugstringOptionalNew slug. Lowercase URL-safe, must remain globally unique.
websitestringOptionalVendor URL. Pass null to clear.
api_keystringOptionalReplace the provider's API key. Write-only: stored encrypted, never returned. Pass null to clear the stored key; omit the field to keep it.
Example requestbash
curl -X PATCH https://api.cortex.cognit-dx.com/v1/admin/ai-providers/a8e3f47c-2b9d-4e1a-9c5f-7d6b8e2a1c34 \
  -H "Authorization: Bearer $CORTEX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"website": "https://www.anthropic.com"}'

Response codes

StatusMeaningBody
404Provider not found.`{ error }`
409A provider with the requested slug already exists.`{ error }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
200 OKjson
{
  "id": "a8e3f47c-2b9d-4e1a-9c5f-7d6b8e2a1c34",
  "name": "Anthropic",
  "slug": "anthropic",
  "website": "https://www.anthropic.com",
  "has_api_key": true,
  "created_at": "2026-05-18T10:24:31.000Z",
  "updated_at": "2026-05-18T10:24:31.000Z"
}

Delete AI provider

Remove a provider from the catalog. Refuses if any model category is still attached — delete those (and their versions) first. Returns 204 on success.

DELETE/v1/admin/ai-providers/:id

Path parameters

NameTypeRequiredDescription
idstringRequiredThe provider's UUID.
Example requestbash
curl -X DELETE https://api.cortex.cognit-dx.com/v1/admin/ai-providers/a8e3f47c-2b9d-4e1a-9c5f-7d6b8e2a1c34 \
  -H "Authorization: Bearer $CORTEX_TOKEN"

Response codes

StatusMeaningBody
204Provider deleted. No response body.—
404Provider not found.`{ error }`
409Provider still has one or more model categories attached.`{ error }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
204 No Contenttext
(empty response body)

List a provider's available models

Return the provider's LIVE model list — every id the vendor's own models API currently serves — so a category's versions can be picked from it. Each row is one vendor model id (the exact string handed to the vendor at inference), with `display_name` (the vendor's own display name, or a readable form of the id — `gpt-5.5-sol` → `GPT 5.5 Sol` — when the vendor publishes none; never null, and exactly what a version created from the row stores), `kind` (`chat`, `image`, `audio`, `embedding` or `other`, classified from the vendor's own type field where it has one and from the id otherwise), `deprecated` (the vendor has announced retirement), `owned_by`, `released_at`, `tracked` (`null`, or the ACTIVE category that already holds this id — a soft-deleted category does not count, so its ids are offered again), and `fields`: the version columns an import would write, built from what the vendor publishes (context window, output limit, pricing, capability flags, modalities) over an honest per-kind skeleton — everything the vendor does not publish is `null`/`false`, never invented — and `vendor`: the raw facts the vendor published, before they are laid over the skeleton. `listing` describes the source: `documented` is false when the vendor has no documented list endpoint and the list is maintained by hand (Z.ai), `docs_url` links the vendor reference, `fetched_at` is when the list was read. Lists are cached server-side for one minute; pass `?refresh=1` to bypass.

GET/v1/admin/ai-providers/:id/available-models

Path parameters

NameTypeRequiredDescription
idstringRequiredThe provider's UUID.

Query parameters

NameTypeRequiredDescription
refreshstringOptional`1` to bypass the one-minute server cache and re-read the vendor.
Example requestbash
curl https://api.cortex.cognit-dx.com/v1/admin/ai-providers/a8e3f47c-2b9d-4e1a-9c5f-7d6b8e2a1c34/available-models \
  -H "Authorization: Bearer $CORTEX_TOKEN"

Response codes

StatusMeaningBody
404Provider not found.`{ error }`
400This provider has no model listing integration (a provider created from the console with a slug Cortex does not integrate). Enter versions manually.`{ error }`
409No API key configured for this provider — add one via `PATCH /admin/ai-providers/:id` first. Cerebras lists from a public catalog and never returns this.`{ error }`
502The vendor's models API failed (network error, non-OK response, timeout, or an endless pagination).`{ error }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
200 OKjson
{
  "data": [
    {
      "id": "claude-opus-5",
      "display_name": "Claude Opus 5",
      "kind": "chat",
      "deprecated": false,
      "owned_by": null,
      "released_at": "2026-07-24T00:00:00.000Z",
      "tracked": {
        "version_id": "4e1f9b27-8c3d-4a65-b2e7-9f0d3c6a1b84",
        "version": "claude-opus-5",
        "is_active": true,
        "family_id": "0c9a7d4e-6b21-4f3a-9e58-2d7b1c4f8a63",
        "family_name": "Claude Opus",
        "family_slug": "claude-opus"
      },
      "fields": {
        "input_modalities": [
          "text",
          "image",
          "documents"
        ],
        "output_modalities": [
          "text"
        ],
        "supports_tool_use": true,
        "supports_streaming": true,
        "supports_structured_output": true,
        "supports_thinking": true,
        "context_window": 1000000,
        "max_output_tokens": 128000,
        "input_cost_per1m": null,
        "output_cost_per1m": null,
        "cached_input_cost_per1m": null,
        "cache_creation_cost_per1m": null,
        "released_at": "2026-07-24T00:00:00.000Z"
      },
      "vendor": {
        "context_window": 1000000,
        "max_output_tokens": 128000,
        "supports_thinking": true,
        "supports_structured_output": true,
        "supports_tool_use": true,
        "input_modalities": [
          "text",
          "image",
          "documents"
        ]
      }
    },
    {
      "id": "claude-sonnet-5",
      "display_name": "Claude Sonnet 5",
      "kind": "chat",
      "deprecated": false,
      "owned_by": null,
      "released_at": "2026-05-01T00:00:00.000Z",
      "tracked": null,
      "fields": {
        "input_modalities": [
          "text",
          "image",
          "documents"
        ],
        "output_modalities": [
          "text"
        ],
        "supports_tool_use": true,
        "supports_streaming": true,
        "supports_structured_output": true,
        "supports_thinking": true,
        "context_window": 1000000,
        "max_output_tokens": 64000,
        "input_cost_per1m": null,
        "output_cost_per1m": null,
        "cached_input_cost_per1m": null,
        "cache_creation_cost_per1m": null,
        "released_at": "2026-05-01T00:00:00.000Z"
      }
    }
  ],
  "listing": {
    "documented": true,
    "docs_url": "https://platform.claude.com/docs/en/api/models-list",
    "fetched_at": "2026-09-14T09:00:00.000Z"
  }
}

Refresh a provider's versions from its live list

Re-read the provider's live model list and bring its tracked versions up to date with what the vendor publishes. For every version whose id the vendor still lists, the vendor's facts (context window, output limit, pricing, capability flags, modalities) are written over the stored values and `last_listed_at` and `upstream_deprecated` are stamped; `updated` counts rows where something changed, `unchanged` the rest. Versions the vendor no longer lists are returned in `unlisted`, and versions the vendor flags as retiring in `deprecated` — as badges for an admin to act on. Refresh never creates a version (use `POST /admin/ai-model-families/:id/import-versions`), never deactivates one, and never touches the stored `version` string, `is_active` or `supports_streaming`. Pass `family_ids` to scope the run to specific categories. `errors` is non-empty on a 200 when the vendor returned an empty list, in which case nothing was compared.

POST/v1/admin/ai-providers/:id/sync-models

Path parameters

NameTypeRequiredDescription
idstringRequiredThe provider's UUID.

Request body

NameTypeRequiredDescription
familyIdsarrayOptionalOptional array of category UUIDs to scope the refresh to. Omit to refresh every category under this provider.
Example requestbash
curl https://api.cortex.cognit-dx.com/v1/admin/ai-providers/a8e3f47c-2b9d-4e1a-9c5f-7d6b8e2a1c34/sync-models \
  -H "Authorization: Bearer $CORTEX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'

Response codes

StatusMeaningBody
404Provider not found.`{ error }`
400This provider has no model listing integration.`{ error }`
409No API key configured for this provider (Cerebras excepted — public catalog).`{ error }`
502The vendor's models API failed.`{ error }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
200 OKjson
{
  "updated": 1,
  "unchanged": 4,
  "unlisted": [
    {
      "version_id": "2c1d9a4e-8b3f-4e6a-95c7-1f0e8d7b6a5c",
      "version": "claude-opus-4-6",
      "family_id": "0c9a7d4e-6b21-4f3a-9e58-2d7b1c4f8a63"
    }
  ],
  "deprecated": [
    {
      "version_id": "b7d2e6f1-3a9c-4e58-8d21-6c4f0a9e2b37",
      "version": "claude-haiku-4-5-20251001"
    }
  ],
  "errors": []
}

Model categories

List model categories

List every model category in the catalog, sorted by name ascending. Pass `?providerId=<uuid>` to scope to a single provider — useful when populating a provider-specific picker.

GET/v1/admin/ai-model-families

Query parameters

NameTypeRequiredDescription
providerIdstringOptionalFilter to one provider's categories. UUID. Omit to return all categories across all providers.
Example requestbash
curl "https://api.cortex.cognit-dx.com/v1/admin/ai-model-families?providerId=a8e3f47c-2b9d-4e1a-9c5f-7d6b8e2a1c34" \
  -H "Authorization: Bearer $CORTEX_TOKEN"

Response codes

StatusMeaningBody
401Missing or invalid credential.`{ error, code, request_id }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
200 OKjson
{
  "data": [
    {
      "id": "d2c5b1a9-4e8f-43d6-b271-5a9c8e3f6d12",
      "provider_id": "a8e3f47c-2b9d-4e1a-9c5f-7d6b8e2a1c34",
      "name": "Claude Sonnet",
      "slug": "claude-sonnet",
      "description": "Anthropic's balanced model category — strong reasoning, lower cost than Opus.",
      "latest_version_id": "67b4e2f9-3a8d-4c1e-9b52-d7a3f6c8e1b5",
      "created_at": "2026-05-18T10:24:31.000Z",
      "updated_at": "2026-05-18T10:24:31.000Z"
    }
  ],
  "total": 0,
  "has_more": false,
  "next_cursor": null
}

Create model category

Create a new model category under a provider. **Slug uniqueness is per-provider, not global** — `claude-sonnet` can exist on Anthropic and on a fictional `claude-sonnet` slug on another provider without collision. If the slug matches a **soft-deleted** (inactive) category of this provider, that category is revived instead: reactivated together with its versions, renamed to the submitted `name`/`description`, and returned with its original id. Once created, attach versions via `POST /admin/ai-model-versions`. The API resource keeps its `ai-model-families` path for compatibility.

POST/v1/admin/ai-model-families

Request body

NameTypeRequiredDescription
providerIdstringRequiredUUID of the parent provider. Must exist.
namestringRequiredDisplay name. 1–100 chars.
slugstringRequiredLowercase URL-safe identifier matching `^[a-z0-9-]+$`. Unique **within the provider** — different providers can reuse the same slug. 1–100 chars.
descriptionstringOptionalFree-form description shown in admin UIs. Pass null to clear.
Example requestbash
curl https://api.cortex.cognit-dx.com/v1/admin/ai-model-families \
  -H "Authorization: Bearer $CORTEX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "provider_id": "a8e3f47c-2b9d-4e1a-9c5f-7d6b8e2a1c34",
    "name": "Claude Sonnet",
    "slug": "claude-sonnet",
    "description": "Anthropic'''s balanced model category — strong reasoning, lower cost than Opus."
  }'

Response codes

StatusMeaningBody
201Category created — or a soft-deleted category with the same slug revived (same id, reactivated with its versions).The AIModelFamily row.
404Provider not found.`{ error }`
409An ACTIVE category with that slug already exists for this provider. (An inactive one is revived instead.)`{ error }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
201 Createdjson
{
  "id": "d2c5b1a9-4e8f-43d6-b271-5a9c8e3f6d12",
  "provider_id": "a8e3f47c-2b9d-4e1a-9c5f-7d6b8e2a1c34",
  "name": "Claude Sonnet",
  "slug": "claude-sonnet",
  "description": "Anthropic's balanced model category — strong reasoning, lower cost than Opus.",
  "latest_version_id": null,
  "created_at": "2026-05-18T10:24:31.000Z",
  "updated_at": "2026-05-18T10:24:31.000Z"
}

Import versions from the provider's live list

Add one or more vendor model ids — rows from `GET /admin/ai-providers/:id/available-models` — to a category as versions. Each version is written with exactly the `fields` the listing showed for that id (the vendor's published facts over a per-kind skeleton), plus its `display_name` as the listing showed it, `upstream_deprecated` and `last_listed_at`. Every id must be in the vendor's current list (400 listing the unknown ones) and must not already be tracked by any ACTIVE category of the same provider (409 naming the category) — a vendor id lives in at most one category per provider, because the worker resolves some versions by that string alone. Versions are created **inactive** unless `is_active` is true: several vendors publish no pricing, and an unpriced active version meters usage at zero. If the category has no `latest_version_id` yet, the newest imported version by release date (or, with no dates, the first listed) is promoted; an existing latest is never moved. The whole import is one transaction.

POST/v1/admin/ai-model-families/:id/import-versions

Path parameters

NameTypeRequiredDescription
idstringRequiredThe category's UUID.

Request body

NameTypeRequiredDescription
model_idsarrayRequired1–100 vendor model ids, each the `id` of a row from the available-models listing, passed through unchanged.
is_activebooleanOptionalCreate the versions active. Default false.
Example requestbash
curl https://api.cortex.cognit-dx.com/v1/admin/ai-model-families/d2c5b1a9-4e8f-43d6-b271-5a9c8e3f6d12/import-versions \
  -H "Authorization: Bearer $CORTEX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"model_ids": ["claude-sonnet-5"]}'

Response codes

StatusMeaningBody
201Versions created.`{ created: AIModelVersion[], latest_version_id }`
400Invalid body, or one or more ids are not in the vendor's current list.`{ error }`
404Category not found (soft-deleted categories count as not found), or its provider not found.`{ error }`
409An id is already tracked by an active category of this provider, or no API key is configured for the provider.`{ error }`
502The vendor's models API failed.`{ error }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
201 Createdjson
{
  "created": [
    {
      "id": "67b4e2f9-3a8d-4c1e-9b52-d7a3f6c8e1b5",
      "model_id": "d2c5b1a9-4e8f-43d6-b271-5a9c8e3f6d12",
      "version": "claude-sonnet-5",
      "input_modalities": [
        "text",
        "image",
        "documents"
      ],
      "output_modalities": [
        "text"
      ],
      "supports_tool_use": true,
      "supports_streaming": true,
      "supports_structured_output": true,
      "supports_thinking": true,
      "capabilities": {},
      "context_window": 200000,
      "max_output_tokens": 64000,
      "input_cost_per1m": 300,
      "output_cost_per1m": 1500,
      "cached_input_cost_per1m": 30,
      "cache_creation_cost_per1m": 375,
      "audio_cost_per1k_minutes": null,
      "display_name": "Claude Sonnet 4.6",
      "last_listed_at": "2026-09-14T09:00:00.000Z",
      "upstream_deprecated": false,
      "is_active": false,
      "released_at": "2026-04-21T00:00:00.000Z",
      "created_at": "2026-05-18T10:24:31.000Z",
      "updated_at": "2026-05-18T10:24:31.000Z"
    }
  ],
  "latest_version_id": "67b4e2f9-3a8d-4c1e-9b52-d7a3f6c8e1b5"
}

Get model category

Return a single category by ID. `latestVersionId` is null until you create a version and explicitly promote it; promotion happens through `PATCH /admin/ai-model-families/:id` with `latestVersionId`.

GET/v1/admin/ai-model-families/:id

Path parameters

NameTypeRequiredDescription
idstringRequiredThe category's UUID.
Example requestbash
curl https://api.cortex.cognit-dx.com/v1/admin/ai-model-families/d2c5b1a9-4e8f-43d6-b271-5a9c8e3f6d12 \
  -H "Authorization: Bearer $CORTEX_TOKEN"

Response codes

StatusMeaningBody
404Category not found.`{ error }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
200 OKjson
{
  "id": "d2c5b1a9-4e8f-43d6-b271-5a9c8e3f6d12",
  "provider_id": "a8e3f47c-2b9d-4e1a-9c5f-7d6b8e2a1c34",
  "name": "Claude Sonnet",
  "slug": "claude-sonnet",
  "description": "Anthropic's balanced model category — strong reasoning, lower cost than Opus.",
  "latest_version_id": "67b4e2f9-3a8d-4c1e-9b52-d7a3f6c8e1b5",
  "created_at": "2026-05-18T10:24:31.000Z",
  "updated_at": "2026-05-18T10:24:31.000Z"
}

Update model category

Patch a category's editable fields. Reassigning to a different provider (`providerId`) is supported but rare — usually only after a vendor rebrand. Slug uniqueness is re-checked against the destination provider's categories. Setting `latestVersionId` promotes the version Cortex actually serves for this category — pass a version's UUID to promote it, or null to clear it.

PATCH/v1/admin/ai-model-families/:id

Path parameters

NameTypeRequiredDescription
idstringRequiredThe category's UUID.

Request body

NameTypeRequiredDescription
providerIdstringOptionalReassign to a different provider. Must exist.
namestringOptionalNew display name. 1–100 chars.
slugstringOptionalNew slug. Lowercase URL-safe. Per-provider uniqueness applies.
descriptionstringOptionalFree-form description. Pass null to clear.
latestVersionIdstringOptionalUUID of the version to promote as this category's served version, or null to clear it. Must belong to this category — a version from another category is rejected.
isActivebooleanOptionalActivate or deactivate the category. Reactivating a soft-deleted category is a plain flag flip — its versions keep their own active state.
Example requestbash
curl -X PATCH https://api.cortex.cognit-dx.com/v1/admin/ai-model-families/d2c5b1a9-4e8f-43d6-b271-5a9c8e3f6d12 \
  -H "Authorization: Bearer $CORTEX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"description": "Anthropic'\''s mid-tier model category. Balanced cost and quality."}'

Response codes

StatusMeaningBody
400`latestVersionId` refers to a version that does not belong to this category.`{ error: "Version does not belong to this category" }`
404Category or destination provider not found.`{ error }`
409Slug collision against another category under the same provider.`{ error }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
200 OKjson
{
  "id": "d2c5b1a9-4e8f-43d6-b271-5a9c8e3f6d12",
  "provider_id": "a8e3f47c-2b9d-4e1a-9c5f-7d6b8e2a1c34",
  "name": "Claude Sonnet",
  "slug": "claude-sonnet",
  "description": "Anthropic's mid-tier model category. Balanced cost and quality.",
  "latest_version_id": "67b4e2f9-3a8d-4c1e-9b52-d7a3f6c8e1b5",
  "created_at": "2026-05-18T10:24:31.000Z",
  "updated_at": "2026-05-18T10:24:31.000Z"
}

Delete model category

Remove a category from the catalog together with all of its versions. If any organization has selected this category in its AI-model configuration, the delete refuses unless `replacementFamilyId` names another active category — in which case those selections are reassigned to the replacement first (pinned to its latest version), all in one transaction. Categories whose versions have recorded usage events are **soft-deleted**: the category and its versions are deactivated but kept, so usage and billing history stays attributable — the response is then `200 { result: "deactivated" }` instead of 204. A soft-deleted category is revived by adding the model back: `POST /admin/ai-model-families` with the same slug. Use `GET /admin/ai-model-families/:id/usage` to inspect selections and recorded usage before deleting.

DELETE/v1/admin/ai-model-families/:id

Path parameters

NameTypeRequiredDescription
idstringRequiredThe category's UUID.

Request body

NameTypeRequiredDescription
replacementFamilyIdstringOptionalUUID of an active category to take over this category's organization AI-model selections. Required when any selection references the category; must be a different, existing, active category.
softbooleanOptionalForce the soft-delete outcome even when the category has no recorded usage: the category and its versions are deactivated and kept. Reverse it later with `PATCH { isActive: true }`.
Example requestbash
curl -X DELETE https://api.cortex.cognit-dx.com/v1/admin/ai-model-families/d2c5b1a9-4e8f-43d6-b271-5a9c8e3f6d12 \
  -H "Authorization: Bearer $CORTEX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"replacementFamilyId": "7f2a9c4e-1d6b-48e3-a5c7-3b8d9e0f2a61"}'

Response codes

StatusMeaningBody
204Category hard-deleted (selections reassigned first when a replacement was given). No response body.—
200Category was soft-deleted (recorded usage, or `soft: true` was passed): category and versions deactivated, rows kept.`{ result: "deactivated" }`
400`replacementFamilyId` is the category itself, or the replacement category is inactive.`{ error }`
404Category or replacement category not found.`{ error }`
409Category is referenced by organization AI-model selections and no replacement was given.`{ error }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
204 No Contenttext
(empty response body)

Get model category usage

List the organization AI-model selections that reference this category — one row per organization and selection key (a capability like `text`, or an activity like `thinking`). An empty list means the category can be deleted without a replacement. `has_recorded_usage` reports whether any of the category's versions have usage events; if true, a DELETE will soft-delete (deactivate) the category rather than remove it.

GET/v1/admin/ai-model-families/:id/usage

Path parameters

NameTypeRequiredDescription
idstringRequiredThe category's UUID.
Example requestbash
curl https://api.cortex.cognit-dx.com/v1/admin/ai-model-families/d2c5b1a9-4e8f-43d6-b271-5a9c8e3f6d12/usage \
  -H "Authorization: Bearer $CORTEX_TOKEN"

Response codes

StatusMeaningBody
404Category not found.`{ error }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
200 OKjson
{
  "data": [
    {
      "organization_id": "b4d8e2a6-9c1f-47e5-8a3b-6d2c9f0e4a17",
      "organization_name": "Acme Corp",
      "capability": "text"
    }
  ],
  "has_recorded_usage": false
}

Model versions

List model versions

List every model version in the catalog, sorted by version string ascending. Pass `?modelId=<uuid>` to scope to one model's versions.

GET/v1/admin/ai-model-versions

Query parameters

NameTypeRequiredDescription
modelIdstringOptionalFilter to one model's versions. UUID. Omit to return every version across every model.
Example requestbash
curl "https://api.cortex.cognit-dx.com/v1/admin/ai-model-versions?modelId=d2c5b1a9-4e8f-43d6-b271-5a9c8e3f6d12" \
  -H "Authorization: Bearer $CORTEX_TOKEN"

Response codes

StatusMeaningBody
401Missing or invalid credential.`{ error, code, request_id }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
200 OKjson
{
  "data": [
    {
      "id": "67b4e2f9-3a8d-4c1e-9b52-d7a3f6c8e1b5",
      "model_id": "d2c5b1a9-4e8f-43d6-b271-5a9c8e3f6d12",
      "version": "claude-sonnet-4-6-20251001",
      "input_modalities": [
        "text",
        "image",
        "documents"
      ],
      "output_modalities": [
        "text"
      ],
      "supports_tool_use": true,
      "supports_streaming": true,
      "supports_structured_output": true,
      "supports_thinking": true,
      "capabilities": {},
      "context_window": 200000,
      "max_output_tokens": 64000,
      "input_cost_per1m": 300,
      "output_cost_per1m": 1500,
      "cached_input_cost_per1m": 30,
      "cache_creation_cost_per1m": 375,
      "audio_cost_per1k_minutes": null,
      "display_name": "Claude Sonnet 4.6",
      "last_listed_at": "2026-09-14T09:00:00.000Z",
      "upstream_deprecated": false,
      "is_active": true,
      "released_at": "2026-04-21T00:00:00.000Z",
      "created_at": "2026-05-18T10:24:31.000Z",
      "updated_at": "2026-05-18T10:24:31.000Z"
    }
  ],
  "total": 0,
  "has_more": false,
  "next_cursor": null
}

Create model version

Register a new version under a model. The `version` string is the vendor identifier (e.g. `claude-sonnet-4-6-20251001`) and is **unique within the model** — different models can have the same version string. Pricing fields are stored as integer **cents per 1,000,000 tokens** (so `inputCostPer1m: 300` means $3.00 per 1M tokens). Modalities accept any combination of `text`, `image`, `audio`, `video`, `embeddings`, `documents`. `display_name` is how the version is listed in the console; when omitted, null or blank it is derived from `version` (`gpt-5.5-sol` → `GPT 5.5 Sol`), so a version is never nameless. `last_listed_at` and `upstream_deprecated` are stamped by import and refresh and cannot be set here.

POST/v1/admin/ai-model-versions

Request body

NameTypeRequiredDescription
modelIdstringRequiredUUID of the parent model. Must exist.
versionstringRequiredVendor version identifier. Unique within the model. 1–100 chars.
displayNamestringOptionalHow the version is listed in the console. Trimmed, ≤200 chars. Omitted, null or blank: derived from `version`.
inputModalitiesarrayOptionalArray of supported input modalities. Each entry: `text`, `image`, `audio`, `video`, `embeddings`, `documents`. Defaults to `[]`.
outputModalitiesarrayOptionalArray of output modalities the model can produce. Same value set as inputModalities. Defaults to `[]`.
supportsToolUsebooleanOptionalWhether the model can call tools / functions. Default false.
supportsStreamingbooleanOptionalWhether the model streams partial completions. Default false.
supportsStructuredOutputbooleanOptionalWhether the model can be constrained to a JSON Schema. Default false.
supportsThinkingbooleanOptionalWhether the model exposes a chain-of-thought / extended-thinking mode. Default false.
capabilitiesobjectOptionalFree-form JSON for any vendor-specific capability flags that don't fit the typed fields above. Defaults to `{}`.
contextWindownumberOptionalMaximum total tokens the model can ingest in a single call. Positive integer. Null when unbounded or unknown.
maxOutputTokensnumberOptionalMaximum tokens the model will emit in a single response. Positive integer. Null when unbounded.
inputCostPer1mnumberOptionalInput token cost in **integer cents per 1M tokens**. Non-negative. Null when pricing is not configured.
outputCostPer1mnumberOptionalOutput token cost in cents per 1M tokens. Non-negative integer. Null when not configured.
cachedInputCostPer1mnumberOptionalCached / cache-read input cost in cents per 1M tokens. Non-negative integer. Null when caching is not priced separately.
cacheCreationCostPer1mnumberOptionalCost to write to the prompt cache, in cents per 1M tokens. Non-negative integer. Null when the vendor doesn't price cache writes separately.
audioCostPer1kMinutesnumberOptionalAudio input cost in cents per 1,000 minutes. Non-negative integer. Null when the model doesn't accept audio or isn't priced for it.
isActivebooleanOptionalWhether the version is selectable by organizations. Default true. Setting false hides it from the catalog endpoint without deleting it.
releasedAtstringOptionalISO-8601 datetime the vendor publicly released this version. Pass null when unknown.
Example requestbash
curl https://api.cortex.cognit-dx.com/v1/admin/ai-model-versions \
  -H "Authorization: Bearer $CORTEX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model_id": "d2c5b1a9-4e8f-43d6-b271-5a9c8e3f6d12",
    "version": "claude-sonnet-4-6-20251001",
    "display_name": "Claude Sonnet 4.6",
    "input_modalities": ["text", "image", "documents"],
    "output_modalities": ["text"],
    "supports_tool_use": true,
    "supports_streaming": true,
    "supports_structured_output": true,
    "supports_thinking": true,
    "context_window": 200000,
    "max_output_tokens": 64000,
    "inputCostPer1m": 300,
    "outputCostPer1m": 1500,
    "cachedInputCostPer1m": 30,
    "cacheCreationCostPer1m": 375,
    "audioCostPer1kMinutes": null,
    "is_active": true,
    "released_at": "2026-04-21T00:00:00Z"
  }'

Response codes

StatusMeaningBody
201Version created.The new AIModelVersion row.
404Category not found.`{ error }`
409A version with that id already exists in this category, or another ACTIVE category of the same provider already tracks it (the error names that category).`{ error }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
201 Createdjson
{
  "id": "67b4e2f9-3a8d-4c1e-9b52-d7a3f6c8e1b5",
  "model_id": "d2c5b1a9-4e8f-43d6-b271-5a9c8e3f6d12",
  "version": "claude-sonnet-4-6-20251001",
  "input_modalities": [
    "text",
    "image",
    "documents"
  ],
  "output_modalities": [
    "text"
  ],
  "supports_tool_use": true,
  "supports_streaming": true,
  "supports_structured_output": true,
  "supports_thinking": true,
  "capabilities": {},
  "context_window": 200000,
  "max_output_tokens": 64000,
  "input_cost_per1m": 300,
  "output_cost_per1m": 1500,
  "cached_input_cost_per1m": 30,
  "cache_creation_cost_per1m": 375,
  "audio_cost_per1k_minutes": null,
  "display_name": "Claude Sonnet 4.6",
  "last_listed_at": "2026-09-14T09:00:00.000Z",
  "upstream_deprecated": false,
  "is_active": true,
  "released_at": "2026-04-21T00:00:00.000Z",
  "created_at": "2026-05-18T10:24:31.000Z",
  "updated_at": "2026-05-18T10:24:31.000Z"
}

Get model version

Return a single version by ID. Pricing is in integer cents per 1,000,000 tokens — divide by 100 for dollars per 1M tokens.

GET/v1/admin/ai-model-versions/:id

Path parameters

NameTypeRequiredDescription
idstringRequiredThe version's UUID.
Example requestbash
curl https://api.cortex.cognit-dx.com/v1/admin/ai-model-versions/67b4e2f9-3a8d-4c1e-9b52-d7a3f6c8e1b5 \
  -H "Authorization: Bearer $CORTEX_TOKEN"

Response codes

StatusMeaningBody
404Version not found.`{ error }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
200 OKjson
{
  "id": "67b4e2f9-3a8d-4c1e-9b52-d7a3f6c8e1b5",
  "model_id": "d2c5b1a9-4e8f-43d6-b271-5a9c8e3f6d12",
  "version": "claude-sonnet-4-6-20251001",
  "input_modalities": [
    "text",
    "image",
    "documents"
  ],
  "output_modalities": [
    "text"
  ],
  "supports_tool_use": true,
  "supports_streaming": true,
  "supports_structured_output": true,
  "supports_thinking": true,
  "capabilities": {},
  "context_window": 200000,
  "max_output_tokens": 64000,
  "input_cost_per1m": 300,
  "output_cost_per1m": 1500,
  "cached_input_cost_per1m": 30,
  "cache_creation_cost_per1m": 375,
  "audio_cost_per1k_minutes": null,
  "display_name": "Claude Sonnet 4.6",
  "last_listed_at": "2026-09-14T09:00:00.000Z",
  "upstream_deprecated": false,
  "is_active": true,
  "released_at": "2026-04-21T00:00:00.000Z",
  "created_at": "2026-05-18T10:24:31.000Z",
  "updated_at": "2026-05-18T10:24:31.000Z"
}

Update model version

Patch a version's fields. Reassigning to a different model is supported (`model_id`); the version-string uniqueness check is re-run against the destination model. Setting `is_active: false` hides the version from the catalog endpoint without deleting it — useful for sunsetting an older model while preserving usage history.

PATCH/v1/admin/ai-model-versions/:id

Path parameters

NameTypeRequiredDescription
idstringRequiredThe version's UUID.

Request body

NameTypeRequiredDescription
modelIdstringOptionalReassign to a different model. Must exist.
versionstringOptionalNew version string. Unique within the (destination) category.
displayNamestringOptionalNew console name. Trimmed, 1–200 chars; blank or null is rejected — a version always has a name.
inputModalitiesarrayOptionalReplacement input modalities array.
outputModalitiesarrayOptionalReplacement output modalities array.
supportsToolUsebooleanOptionalTool-use capability flag.
supportsStreamingbooleanOptionalStreaming capability flag.
supportsStructuredOutputbooleanOptionalStructured-output capability flag.
supportsThinkingbooleanOptionalExtended-thinking capability flag.
capabilitiesobjectOptionalReplacement free-form capabilities object.
contextWindownumberOptionalMaximum input tokens. Pass null to clear.
maxOutputTokensnumberOptionalMaximum output tokens. Pass null to clear.
inputCostPer1mnumberOptionalInput cost in cents per 1M tokens. Pass null to clear.
outputCostPer1mnumberOptionalOutput cost in cents per 1M tokens. Pass null to clear.
cachedInputCostPer1mnumberOptionalCached-input cost in cents per 1M tokens. Pass null to clear.
cacheCreationCostPer1mnumberOptionalCost to write to the prompt cache, in cents per 1M tokens. Pass null to clear.
audioCostPer1kMinutesnumberOptionalAudio input cost in cents per 1,000 minutes. Pass null to clear.
isActivebooleanOptionalToggle availability. Setting false sunsets the version.
releasedAtstringOptionalISO-8601 datetime. Pass null to clear.
Example requestbash
curl -X PATCH https://api.cortex.cognit-dx.com/v1/admin/ai-model-versions/67b4e2f9-3a8d-4c1e-9b52-d7a3f6c8e1b5 \
  -H "Authorization: Bearer $CORTEX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"is_active": false}'

Response codes

StatusMeaningBody
400Invalid body (for example a blank or null `display_name`), or the target category (model_id) belongs to a different provider than the version's current category.`{ error }`
404Version or destination category not found.`{ error }`
409The new version string collides with another version in the same category, or another ACTIVE category of the same provider already tracks it (the error names that category).`{ error }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
200 OKjson
{
  "id": "67b4e2f9-3a8d-4c1e-9b52-d7a3f6c8e1b5",
  "model_id": "d2c5b1a9-4e8f-43d6-b271-5a9c8e3f6d12",
  "version": "claude-sonnet-4-6-20251001",
  "input_modalities": [
    "text",
    "image",
    "documents"
  ],
  "output_modalities": [
    "text"
  ],
  "supports_tool_use": true,
  "supports_streaming": true,
  "supports_structured_output": true,
  "supports_thinking": true,
  "capabilities": {},
  "context_window": 200000,
  "max_output_tokens": 64000,
  "input_cost_per1m": 300,
  "output_cost_per1m": 1500,
  "cached_input_cost_per1m": 30,
  "cache_creation_cost_per1m": 375,
  "audio_cost_per1k_minutes": null,
  "display_name": "Claude Sonnet 4.6",
  "last_listed_at": "2026-09-14T09:00:00.000Z",
  "upstream_deprecated": false,
  "is_active": false,
  "released_at": "2026-04-21T00:00:00.000Z",
  "created_at": "2026-05-18T10:24:31.000Z",
  "updated_at": "2026-05-18T10:24:31.000Z"
}

Delete model version

Permanently remove a version from the catalog. Three guards apply: (1) refuses if any category points at this version as its `latest_version_id` — promote a different version on that category first; (2) refuses if any organization has pinned this version in its AI-model selections — point them at another version first; (3) refuses if any usage event references this version — usage history blocks deletion to preserve audit integrity. Sunsetting via `PATCH { is_active: false }` is usually a better choice for retired-but-historical versions.

DELETE/v1/admin/ai-model-versions/:id

Path parameters

NameTypeRequiredDescription
idstringRequiredThe version's UUID.
Example requestbash
curl -X DELETE https://api.cortex.cognit-dx.com/v1/admin/ai-model-versions/67b4e2f9-3a8d-4c1e-9b52-d7a3f6c8e1b5 \
  -H "Authorization: Bearer $CORTEX_TOKEN"

Response codes

StatusMeaningBody
204Version deleted. No response body.—
404Version not found.`{ error }`
409Version is a category's latest version, is pinned by an organization's selection, or has usage history attached.`{ error }`
403Admin access required — caller lacks the system admin role or the credential cannot reach admin routes.`{ error, code, request_id }`
204 No Contenttext
(empty response body)