Skip to main content
GET
JavaScript
Models are workspace resources, not free-text strings. Before you set modelConfig.modelId on a variation, this is where you find out what exists and what it costs.

Prices are cents, as strings

inputPricePerMillionTokens and outputPricePerMillionTokens are cents per million tokens, serialized as strings because they are 64-bit integers.
Parse them as integers, not floats, and divide by 100 only at the point you render a currency. Pair them with the token counts from context windows to price a run:

maxInputTokens drives compaction

A variation’s compactionConfig.triggerThreshold is a fraction of this number, not an absolute token count. The same 0.75 threshold means 750,000 tokens on a million-token model and 150,000 on a 200,000-token one. That is the trap when you swap models: the threshold moves with the model, and nothing warns you.
A model with no maxInputTokens never triggers compaction at all, so a long objective on it grows until it fails.

The prefix filter matches names, not IDs

prefix is documented as “Filter by ID prefix.” It filters by the model’s display name, case-insensitively, and matches nothing that looks like an ID.
It also cannot span a space, so prefix=Claude Opus returns nothing even though every Claude model’s name begins with it. Only single-word prefixes work.
When you already know which model you want, skip the filter and fetch it directly. GET /models/{id} takes the external_id: form:
That is also the form to use in modelConfig.modelId. Cadenya resolves it and stores the canonical model_... ID, so a variation reads back with the canonical one.

What a model record holds

Enabled and disabled

A model must be STATE_ENABLED for a variation to reference it, and the two guards hold each other up:
  • Creating or updating a variation onto a disabled model is a 400 on spec.model_id.
  • Disabling a model while any variation references it is a 400.
So a running objective can never find its model disabled underneath it. To retire a model, swap the variations off it first, then disable it.

Create a variation

Where modelConfig.modelId and temperature are set.

Swap models on variations

Migrate a whole workspace off a deprecated model.

List context windows

The token counts you multiply by these prices.

Get objective diagnostics

Where a live objective’s context window is going.

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Path Parameters

workspaceId
string
required

Workspace ID.

Example:

"workspace_01HXKD2E5NQM3T9AYWCF133E3Q"

Query Parameters

limit
integer<int32>

Maximum number of results to return

cursor
string

Pagination cursor from previous response

prefix
string

Filter by a prefix of the model's display name, external id, or id (case-insensitive). A model's external id is the form used in modelConfig.modelId, so a caller holding that can narrow the list by it.

query
string

Free-form search query

state
enum<string>

Filter by model state

Available options:
STATE_UNSPECIFIED,
STATE_ENABLED,
STATE_DISABLED
aiProviderKeyId
string

Filter to models provisioned on a specific AI provider key. Accepts the key's id or an "external_id:"-prefixed slug.

isAssigned
boolean

Filter models to only ones assigned to an active agent variation/agent. Draft agents count as assigned; archived agents do not. Assignment does not imply recent traffic — see ModelInfo.last_used_at for that.

labels
string

Filters by metadata labels. Comma-separated key=value pairs, e.g. "env=prod,team=ai". A resource matches only if every pair matches exactly (AND semantics).

sortOrder
string

Sort order for results (asc or desc by creation time)

includeInfo
boolean

When true, populate each item's info (e.g. the AI provider), at the cost of extra lookups.

Response

OK

List models response

items
object[]
pagination
object

Page carries cursor-based pagination state. There is no total: the cursor walks the result set without ever counting it, and a count would cost a second query on every list.