Skip to content

Publish a Revision

POST/v1/routers/{id}/publish

Overview

Requires an active owner, admin, or developer session in the named workspace; viewer and billing-only roles cannot mutate.

Routing and provider details

Inference API keys are rejected. For cookie sessions, every POST and PATCH requires browser same-origin proof: Sec-Fetch-Site: same-origin, or Origin equal to the configured public request origin. A Bearer sess.* session does not use cookie authentication. JSON request bodies are limited to 131072 bytes.

Requires the current generation and Idempotency-Key. Revalidates all routes, variants and fallback candidates against current workspace and catalog evidence, then atomically creates the next immutable revision, advances active_revision/generation and records an audit event. The draft is preserved. Invalid or ineligible publication creates no revision or command claim. At most 1000 revisions are retained per router.

After publication, Chat Completions, Responses and Messages requests with model router/<slug> use the new revision immediately. Requests that send router_revision keep the revision they pin. Every request rechecks the revision against current policy, so a model switched off later makes the revision fail with 422 until you publish a fix or roll back.

Authorization

Authorizationstring · headerRequired

Workspace session token sent as Bearer <token>. Authentication guide

Parameters

idpath · stringRequired

Router identity in the explicitly supplied workspace.

Idempotency-Keyheader · stringRequired

Required for create, duplicate and publish. Scoped to workspace, authenticated actor, operation and source router. The same key and normalized request replay the committed response without new side effects; a changed request returns 409. A replay returns the original generation even if the router has since changed or been archived, so reload before the next mutation. Current membership is checked before replay. Failed transactions do not reserve the key. No inference idempotency or automatic activation is implied.

Request Body

application/json
workspace_idstringRequired
expected_generationintegerRequired

Current generation observed by the caller. Re-read the router after a 409; do not overwrite a concurrent edit.

Minimum 1 · Maximum 2147483646

Responses

200Operation completed.
application/json
generationintegerRequired

Optimistic version of the router record. Every successful mutation increments it. Send the observed value as expected_generation; stale values return 409.

Minimum 1 · Maximum 2147483647

routerobjectRequired
Show nested fields
idstringRequired
workspace_idstringRequired
slugstringRequired
aliasstringRequired

Example: "router/coding"

namestringRequired
taskstringRequired
generationintegerRequired

Optimistic version of the router record. Every successful mutation increments it. Send the observed value as expected_generation; stale values return 409.

Minimum 1 · Maximum 2147483647

draftobjectRequired

Versioned declarative LLM router configuration, normalized to at most 65536 UTF-8 JSON bytes. Unknown fields and undocumented null values are rejected. Structurally valid but incomplete drafts are permitted; validation/publication enforce final-default, nonempty pools, uniqueness, exact weights and current model eligibility.

Example: {"schema_version":1,"task":"llm","protocol":"chat","requirements":[],"defaults":{},"request_overrides":[],"policy":{"max_input_tokens":128000,"max_output_tokens":8192,"deadline_ms":120000,"regions":[],"zero_retention":false},"routes":[{"id":"default","name":"Default","condition":null,"defaults":{},"variants":[{"id":"primary","name":"Primary","weight":100,"selection":{"mode":"ordered","models":[]},"defaults":{}}]}]}

Show nested fields
schema_versionintegerRequired
taskstringRequired
protocolstringRequired

Values: "chat""responses""messages"

requirementsstring[]

Default: []

Show nested fields

See the OpenAPI schema for this nested object.

defaultsobject

Field-wise inheritance: router defaults, then route defaults, then variant defaults, then explicitly permitted request parameters. Omitted fields inherit; null does not clear a field. max_tokens defaults to policy.max_output_tokens and cannot exceed that policy. Every effective and overridable parameter must be supported by every selected model.

Show nested fields
max_tokensinteger

Minimum 1 · Maximum 1000000

temperaturenumber

Minimum 0 · Maximum 2

top_pnumber

Minimum 0 · Maximum 1

system_promptstring
request_overridesstring[]

Default: []

Show nested fields

See the OpenAPI schema for this nested object.

policyobject

Declarative upper limits, intersected with current operator/workspace/model restrictions. A model must support the full configured input plus output context budget. Region and zero-retention requirements cannot widen workspace policy.

Show nested fields
max_input_tokensinteger

Default: 128000

Minimum 1 · Maximum 1000000

max_output_tokensinteger

Default: 8192

Minimum 1 · Maximum 1000000

deadline_msinteger

Default: 120000

Minimum 1000 · Maximum 1800000

regionsstring[]

Regions every route requires: us, eu or a documented country code, any of which an endpoint may process in. Empty or global means none. Each model must have an endpoint documented in one of them, and requests can narrow it but never widen it. A region no endpoint documents is refused with 422 on create, update and duplicate, and validate reports it as region_unavailable.

Default: []

Show nested fields

See the OpenAPI schema for this nested object.

zero_retentionboolean

Reserved. Router-level zero retention is not available, so true is refused with 422 and validate reports zero_retention_unavailable. Workspace Privacy settings, including zero data retention per provider family, still apply to every route.

Default: false

max_priceobject
Show nested fields

See the OpenAPI schema for this nested object.

routesobject[]Required
Show nested fields

See the OpenAPI schema for this nested object.

active_revisioninteger | nullRequired
Show nested fields
Option 1: integer

integer

Option 2: null

null

archived_atstring | nullRequired
Show nested fields
Option 1: string

string

Option 2: null

null

created_atstringRequired
updated_atstringRequired
revisionobjectRequired

Immutable publication evidence. config_hash is SHA-256 of the canonical normalized configuration. catalog_revision records publication-time evidence; execution must still revalidate current eligibility. A restore is a new revision referring to its source via restored_from.

Show nested fields
router_idstringRequired
revisionintegerRequired

Minimum 1 · Maximum 1000

schema_versionintegerRequired
configobjectRequired

Versioned declarative LLM router configuration, normalized to at most 65536 UTF-8 JSON bytes. Unknown fields and undocumented null values are rejected. Structurally valid but incomplete drafts are permitted; validation/publication enforce final-default, nonempty pools, uniqueness, exact weights and current model eligibility.

Example: {"schema_version":1,"task":"llm","protocol":"chat","requirements":[],"defaults":{},"request_overrides":[],"policy":{"max_input_tokens":128000,"max_output_tokens":8192,"deadline_ms":120000,"regions":[],"zero_retention":false},"routes":[{"id":"default","name":"Default","condition":null,"defaults":{},"variants":[{"id":"primary","name":"Primary","weight":100,"selection":{"mode":"ordered","models":[]},"defaults":{}}]}]}

Show nested fields
schema_versionintegerRequired
taskstringRequired
protocolstringRequired

Values: "chat""responses""messages"

requirementsstring[]

Default: []

Show nested fields

See the OpenAPI schema for this nested object.

defaultsobject

Field-wise inheritance: router defaults, then route defaults, then variant defaults, then explicitly permitted request parameters. Omitted fields inherit; null does not clear a field. max_tokens defaults to policy.max_output_tokens and cannot exceed that policy. Every effective and overridable parameter must be supported by every selected model.

Show nested fields
max_tokensinteger

Minimum 1 · Maximum 1000000

temperaturenumber

Minimum 0 · Maximum 2

top_pnumber

Minimum 0 · Maximum 1

system_promptstring
request_overridesstring[]

Default: []

Show nested fields

See the OpenAPI schema for this nested object.

policyobject

Declarative upper limits, intersected with current operator/workspace/model restrictions. A model must support the full configured input plus output context budget. Region and zero-retention requirements cannot widen workspace policy.

Show nested fields
max_input_tokensinteger

Default: 128000

Minimum 1 · Maximum 1000000

max_output_tokensinteger

Default: 8192

Minimum 1 · Maximum 1000000

deadline_msinteger

Default: 120000

Minimum 1000 · Maximum 1800000

regionsstring[]

Regions every route requires: us, eu or a documented country code, any of which an endpoint may process in. Empty or global means none. Each model must have an endpoint documented in one of them, and requests can narrow it but never widen it. A region no endpoint documents is refused with 422 on create, update and duplicate, and validate reports it as region_unavailable.

Default: []

Show nested fields

See the OpenAPI schema for this nested object.

zero_retentionboolean

Reserved. Router-level zero retention is not available, so true is refused with 422 and validate reports zero_retention_unavailable. Workspace Privacy settings, including zero data retention per provider family, still apply to every route.

Default: false

max_priceobject
Show nested fields

See the OpenAPI schema for this nested object.

routesobject[]Required
Show nested fields

See the OpenAPI schema for this nested object.

config_hashstringRequired
catalog_revisionstringRequired
restored_frominteger | nullRequired
Show nested fields
Option 1: integer

integer

Option 2: null

null

created_bystring | nullRequired
Show nested fields
Option 1: string

string

Option 2: null

null

created_atstringRequired
400Request validation failed.
application/json
errorobjectRequired
Show nested fields
codestringRequired
messagestringRequired
paramstring | null
request_idstring | null
metadataobject

Typed detail for some refusals. budget_exceeded (402): limit (key_budget or workspace_budget) and budget with scope, period, limit, usage and resets_at. key_limit_exceeded (402): limit key_spend_limit. access_denied (403): policy (workspace or key), rule (models, providers or products), product, provider and model.

401Authentication is missing or invalid.
application/json
errorobjectRequired
Show nested fields
codestringRequired
messagestringRequired
paramstring | null
request_idstring | null
metadataobject

Typed detail for some refusals. budget_exceeded (402): limit (key_budget or workspace_budget) and budget with scope, period, limit, usage and resets_at. key_limit_exceeded (402): limit key_spend_limit. access_denied (403): policy (workspace or key), rule (models, providers or products), product, provider and model.

403Authenticated principal lacks permission.
application/json
errorobjectRequired
Show nested fields
codestringRequired
messagestringRequired
paramstring | null
request_idstring | null
metadataobject

Typed detail for some refusals. budget_exceeded (402): limit (key_budget or workspace_budget) and budget with scope, period, limit, usage and resets_at. key_limit_exceeded (402): limit key_spend_limit. access_denied (403): policy (workspace or key), rule (models, providers or products), product, provider and model.

404Resource was not found.
application/json
errorobjectRequired
Show nested fields
codestringRequired
messagestringRequired
paramstring | null
request_idstring | null
metadataobject

Typed detail for some refusals. budget_exceeded (402): limit (key_budget or workspace_budget) and budget with scope, period, limit, usage and resets_at. key_limit_exceeded (402): limit key_spend_limit. access_denied (403): policy (workspace or key), rule (models, providers or products), product, provider and model.

409Stale expected_generation, archived state, reserved slug, or an Idempotency-Key reused with different command content. Re-read current state before editing; do not blindly retry with a new generation.
application/json
errorobjectRequired
Show nested fields
codestringRequired
messagestringRequired
paramstring | null
request_idstring | null
metadataobject

Typed detail for some refusals. budget_exceeded (402): limit (key_budget or workspace_budget) and budget with scope, period, limit, usage and resets_at. key_limit_exceeded (402): limit key_spend_limit. access_denied (403): policy (workspace or key), rule (models, providers or products), product, provider and model.

413JSON body exceeds 131072 bytes.
application/json
errorobjectRequired
Show nested fields
codestringRequired
messagestringRequired
paramstring | null
request_idstring | null
metadataobject

Typed detail for some refusals. budget_exceeded (402): limit (key_budget or workspace_budget) and budget with scope, period, limit, usage and resets_at. key_limit_exceeded (402): limit key_spend_limit. access_denied (403): policy (workspace or key), rule (models, providers or products), product, provider and model.

422Draft cannot publish or the requested restore is no longer eligible under current policy/catalog. Also used for workspace router or revision limits. Use validate for structured blocking issues. No revision, active-pointer change or idempotency claim is committed on failure.
application/json
errorobjectRequired
Show nested fields
codestringRequired
messagestringRequired
paramstring | null
request_idstring | null
metadataobject

Typed detail for some refusals. budget_exceeded (402): limit (key_budget or workspace_budget) and budget with scope, period, limit, usage and resets_at. key_limit_exceeded (402): limit key_spend_limit. access_denied (403): policy (workspace or key), rule (models, providers or products), product, provider and model.

429Rate limit exceeded.
application/json
errorobjectRequired
Show nested fields
codestringRequired
messagestringRequired
paramstring | null
request_idstring | null
metadataobject

Typed detail for some refusals. budget_exceeded (402): limit (key_budget or workspace_budget) and budget with scope, period, limit, usage and resets_at. key_limit_exceeded (402): limit key_spend_limit. access_denied (403): policy (workspace or key), rule (models, providers or products), product, provider and model.

500Internal server error.
application/json
errorobjectRequired
Show nested fields
codestringRequired
messagestringRequired
paramstring | null
request_idstring | null
metadataobject

Typed detail for some refusals. budget_exceeded (402): limit (key_budget or workspace_budget) and budget with scope, period, limit, usage and resets_at. key_limit_exceeded (402): limit key_spend_limit. access_denied (403): policy (workspace or key), rule (models, providers or products), product, provider and model.