Skip to content

API reference — Model catalog

The model catalog is the registry of AI models available in Arbitex. Each entry maps a provider (e.g., anthropic, openai) and a model ID (e.g., claude-3-5-sonnet-20241022) to a set of capabilities and cost metadata. Models must be in the catalog (and have is_active: true) before they can be referenced in routing rules or API requests.

All model catalog endpoints are admin-only. Authentication: Authorization: Bearer arb_live_<admin-key>.

Base path: GET|POST|PUT|DELETE /api/v1/admin/models/catalog


Field Type Description
id UUID Internal record identifier
provider string Provider name (e.g., anthropic, openai, azure)
model_id string Provider-specific model identifier
display_name string Human-readable name for UI display
is_active boolean Whether the model is available for routing
is_default boolean Whether this is the default model for its provider
capabilities object Model capability flags (see below)
cost_per_input_token float Cost per input token in USD (nullable)
cost_per_output_token float Cost per output token in USD (nullable)
created_at datetime ISO 8601 creation timestamp

Capabilities object:

Field Type Description
streaming boolean Supports streaming responses
function_calling boolean Supports function/tool calling
vision boolean Supports image inputs
structured_output boolean Supports structured JSON output
embeddings boolean Supports embeddings generation
max_context_window integer Maximum context window in tokens

Returned by /discover — includes catalog membership status:

Field Type Description
provider string Provider name
model_id string Provider-specific model ID
display_name string Human-readable name
max_tokens integer Maximum context window
supports_streaming boolean Streaming support
already_in_catalog boolean Whether this model is already in the catalog

GET /api/v1/admin/models/catalog/

Returns paginated ModelConfig records with optional filtering.

Query parameters:

Parameter Type Default Description
page integer 1 Page number (1-based)
page_size integer 20 Records per page (1–200)
search string Case-insensitive substring match against display_name and model_id
provider string Exact provider name filter
is_active boolean Filter by active status

Request:

Terminal window
GET /api/v1/admin/models/catalog/?provider=anthropic&is_active=true
Authorization: Bearer arb_live_your-admin-key

Response (200):

{
"items": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"provider": "anthropic",
"model_id": "claude-3-5-sonnet-20241022",
"display_name": "Claude 3.5 Sonnet",
"is_active": true,
"is_default": false,
"capabilities": {
"streaming": true,
"function_calling": true,
"vision": true,
"structured_output": true,
"embeddings": false,
"max_context_window": 200000
},
"cost_per_input_token": 0.000003,
"cost_per_output_token": 0.000015,
"created_at": "2026-03-01T00:00:00Z"
}
],
"total": 12,
"page": 1,
"page_size": 20
}

POST /api/v1/admin/models/catalog/

Creates a new ModelConfig record. Returns 409 Conflict if a record with the same provider + model_id already exists.

Request body:

Field Required Description
provider Yes Provider name
model_id Yes Provider-specific model ID
display_name Yes Human-readable name
is_active No Default: true
capabilities No Capability flags object
cost_per_input_token No Cost per input token in USD
cost_per_output_token No Cost per output token in USD

Request:

Terminal window
POST /api/v1/admin/models/catalog/
Authorization: Bearer arb_live_your-admin-key
Content-Type: application/json
{
"provider": "openai",
"model_id": "gpt-4o-mini",
"display_name": "GPT-4o mini",
"is_active": true,
"capabilities": {
"streaming": true,
"function_calling": true,
"vision": true,
"structured_output": true,
"embeddings": false,
"max_context_window": 128000
},
"cost_per_input_token": 0.00000015,
"cost_per_output_token": 0.0000006
}

Response (201 Created): Returns the created ModelConfig object.

Error (409 Conflict):

{ "detail": "A catalog entry for provider 'openai' and model_id 'gpt-4o-mini' already exists." }

GET /api/v1/admin/models/catalog/{model_config_id}

Response (200): Returns the matching ModelConfig object.

Error (404 Not Found):

{ "detail": "Model catalog entry not found" }

PUT /api/v1/admin/models/catalog/{model_config_id}

Partial update — only non-null fields are applied.

Updatable fields: display_name, is_active, is_default, capabilities, cost_per_input_token, cost_per_output_token.

Request:

Terminal window
PUT /api/v1/admin/models/catalog/3fa85f64-5717-4562-b3fc-2c963f66afa6
Authorization: Bearer arb_live_your-admin-key
Content-Type: application/json
{
"is_active": false,
"cost_per_output_token": 0.000018
}

Response (200): Returns the updated ModelConfig object.


DELETE /api/v1/admin/models/catalog/{model_config_id}

Permanently removes the catalog entry.

Response: 204 No Content

Error (404 Not Found): Entry not found.


GET /api/v1/admin/models/catalog/discover

Queries all registered provider adapters for their available models and returns the results annotated with already_in_catalog. Providers that are unavailable or return an error are skipped (no failure — the response includes results from available providers only).

Request:

Terminal window
GET /api/v1/admin/models/catalog/discover
Authorization: Bearer arb_live_your-admin-key

Response (200):

[
{
"provider": "anthropic",
"model_id": "claude-opus-4-6",
"display_name": "Claude Opus 4.6",
"max_tokens": 200000,
"supports_streaming": true,
"already_in_catalog": false
},
{
"provider": "anthropic",
"model_id": "claude-3-5-sonnet-20241022",
"display_name": "Claude 3.5 Sonnet",
"max_tokens": 200000,
"supports_streaming": true,
"already_in_catalog": true
}
]

Use this endpoint to identify new provider models that have not yet been imported into the catalog.


POST /api/v1/admin/models/catalog/sync

Queries all registered provider adapters (same as /discover) and creates new catalog entries for any provider+model_id pairs not already in the catalog. Existing entries are left unchanged. The operation is idempotent.

Request:

Terminal window
POST /api/v1/admin/models/catalog/sync
Authorization: Bearer arb_live_your-admin-key

Response (200): Returns the list of newly created ModelConfig records. An empty array means all discovered models were already in the catalog.

[
{
"id": "abc12345-...",
"provider": "anthropic",
"model_id": "claude-opus-4-6",
"display_name": "Claude Opus 4.6",
"is_active": true,
"is_default": false,
"capabilities": {
"streaming": true,
"function_calling": false,
"vision": false,
"structured_output": false,
"embeddings": false,
"max_context_window": 200000
},
"cost_per_input_token": null,
"cost_per_output_token": null,
"created_at": "2026-03-12T14:00:00Z"
}
]

PATCH /api/v1/admin/models/catalog/bulk

Sets is_active on multiple catalog entries in a single operation. UUIDs that do not match any record are silently ignored.

Request body:

Field Type Required Description
model_ids UUID[] Yes List of ModelConfig record UUIDs to update
is_active boolean Yes Target active state

Request:

Terminal window
PATCH /api/v1/admin/models/catalog/bulk
Authorization: Bearer arb_live_your-admin-key
Content-Type: application/json
{
"model_ids": [
"3fa85f64-5717-4562-b3fc-2c963f66afa6",
"7c8d9e0f-1234-5678-abcd-ef0123456789"
],
"is_active": false
}

Response (200): Returns the list of updated ModelConfig records.


  1. Configure the provider adapter with credentials in the Platform environment.
  2. Call GET /discover to see available models.
  3. Call POST /sync to import them all.
  4. Update cost metadata for billing accuracy: PUT /catalog/{id} with cost_per_input_token and cost_per_output_token.
  5. Verify models appear as routing targets in the admin console.

When a provider retires a model:

  1. PUT /catalog/{id} with { "is_active": false } — existing routing rules will fail over to alternatives.
  2. Update routing rules that reference the deprecated model.
  3. Optionally DELETE /catalog/{id} to remove the record.