Search

↑↓ to move↵ to openesc to closetop 6 documentation results

Book a demoTry TokenTriage

In development · Explore the product preview. Join the launch list or book a walkthrough.

Browse docs

Gateway configuration reference

The gateway-config/v1 document, the named refusals with their statuses, the builder operations, and the pinning vocabulary.

ReferenceLast updated

On this page

A managed gateway’s configuration is one JSON document per gateway and environment, plus a closed list of names the control plane answers with when it declines to store or compile one. This page describes both, and the operations that read and write them.

It mirrors the shipped contract: the document port (internal/control/foundation/gatewayconfig), the lane’s problem map, and the operation table the SDK and the CLI pin. For the task flow that produces a document, read Configure, test and promote a gateway.

The gateway-config/v1 document

One document describes one gateway in one environment. The same gateway has a different document in QA than in Production, and the environment is part of the document rather than only part of its address.

The document carries references and dials, not content: inventory target ids, pinned (policy_id, policy_revision) pairs, guardrail profile revisions, and slot bindings. The policy content itself lives in the policy ledger, which is why two gateways can pin the same revision without copying it.

Field Type What it holds
schema_version string gateway-config/v1, the one accepted value
gateway_id string the gateway this document configures
environment_id string the environment this document configures
model_choices array the models this gateway may call, with their dials
routes array ordered first-match branches, default route last
input_protection object the guardrail attachment that sees the request
output_protection object the guardrail attachment that sees the answer
connection_bindings array one provider connection per upstream slot

Model choices

A model choice names one entry of the operator inventory the workspace may point at. A workspace can name a target; it does not create one.

Field Type What it holds
id string mc_ plus twelve base58 characters, gateway-private
label string, optional the name a colleague reads
target_id string an inventory target id, checked for eligibility by the service
settings.temperature number, optional absent and zero are different documents
settings.max_output_tokens integer, optional above zero when present
settings.timeout_ms integer, optional above zero when present

Routes

Routes evaluate in slice order and the first match wins, so the order of the array is the routing semantics rather than a rendering detail.

Field Type What it holds
id string rt_ plus twelve base58 characters, gateway-private
label string, optional the name the route list shows
predicate object or null null marks the default route
policy_id string a policy in the caller’s own workspace
policy_revision integer a revision above zero, not a head
model_choice_id string a model_choices[].id in this document
fallback_model_choice_id string, optional a second choice, different from the primary

A predicate is one registered fact, one operator and one value from that fact’s closed set. v1 registers one fact.

fact op value
request.stream is true or false

A fact outside that table is declined by name instead of becoming a branch that matches nothing.

Protection attachments

input_protection and output_protection carry the same three fields, and both pin a revision.

Field Type What it holds
profile_id string the gateway-local guardrail profile
profile_revision integer a revision above zero, not a head
disabled_rule_ids array of string, optional inherited rules turned off here; duplicates are declined

A required company or workspace rule is not removable through that list. The composer puts mandatory bindings first in each phase, and the more restrictive action wins, ordered block, modify, monitor, simulate.

Connection bindings

A slot id is the inventory upstream’s name, which is why a slot maps to a connection and not to a model: several models of one upstream share one credential.

Field Type What it holds
slot_id string the upstream name of the targets bound here
connection_id string a saved provider connection this environment may bind
purpose string application, playground, comparison, judge or connection_validation

A release binds the application purpose. The other four name the same closed set the connection grants use.

Constraints

The document port validates offline: the same bytes are accepted or declined on any machine, with no store, clock or network involved.

  1. schema_version equals gateway-config/v1, and gateway_id and environment_id are both set.
  2. model_choices is non-empty, its ids are unique, and every target_id is set.
  3. routes is non-empty, its ids are unique, and no two predicates are identical.
  4. One route has predicate: null, and it is the last element.
  5. Every model_choice_id and fallback_model_choice_id resolves inside this document, and a fallback differs from its own primary.
  6. Every pinned revision is above zero.
  7. Each slot_id appears in at most one binding, and each purpose is in the closed set.

The first problem is returned, naming the field and the array index that produced it.

Identifier grammar

Model-choice and route ids are minted inside one draft and mean nothing outside it. Both follow the platform’s id discipline: a prefix plus twelve characters from the base58 alphabet 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz, which omits 0, O, I and l.

Prefix Names Scope
mc_ a model choice one gateway draft
rt_ a route one gateway draft

Ids the document points at are minted elsewhere and carry their own prefixes: gw_ a gateway, env_ an environment, pc_ a provider connection, rtp_ a routing policy.

Canonical bytes

The canonical encoding sorts object members by key byte order, keeps arrays in place, and emits no insignificant whitespace. It validates first, so a document the port declines has no canonical form and cannot reach a digest through the door a valid one uses. Reordering the struct that describes the document cannot move a digest.

Named refusals and their statuses

Each named answer below is an RFC 7807 problem body whose type is the slug and whose status is the one in this table. The pairing is closed: a handler producing a slug whose status disagrees with the table serves a 500 instead, so the two cannot drift apart.

Slug Status What it reports
draft_revision_stale 412 somebody saved first; the body carries the winner’s revision and document
head_revision_stale 412 the deployment head or the policy head moved since the form read it
draft_conflict 409 two writers changed one draft in a way a single save cannot represent
model_choice_referenced 409 a deleted model choice is still selected by routes, which are listed
environment_not_active 409 the environment is retiring or retired, so drafts, releases and deploys are closed
environment_has_references 409 retirement is blocked; the body carries the reference report
provider_test_required 409 the destination requires provider evidence and none is recorded
provider_test_stale 409 a test is recorded against a different effective digest
rollback_incompatible 409 the prior release no longer validates under today’s controls and grants
connection_context_changed 409 a bound connection’s provider, endpoint or account label moved
mandatory_generation_stale 409 the required controls changed between the review and the apply
validation_failed 422 the compiler’s diagnostics, each at its own JSON pointer
policy_document_not_composable 422 a shared policy’s document is not a single tier leaf or one cascade
inventory_target_ineligible 422 a model choice points at a target this environment may not use
connection_slot_unbound 422 a slot the compiled artifact dispatches to has no connection
default_route_missing 422 the compiled artifact has no unconditional route
connection_not_eligible 403 the caller or the environment may not bind that connection
environment_protected_deploy_denied 403 the caller holds deploy but not deploy.protected here
policy_revision_not_found 404 a revision nobody published and one in another company read alike
release_digest_mismatch 503 the two compile paths produced different digests, so nothing is served
Which diagnostics stop a save and which are warnings

default_route_missing, default_route_not_last, duplicate_route_condition, policy_revision_not_found, policy_reference_cycle and inventory_target_ineligible are validation errors wherever they appear. unreachable_route_condition and model_choice_unreferenced are warnings when you inspect a draft and errors when you create a release from it, so an experiment may carry an unused model and a release may not.

Operations

Every path below is relative to the lane base /portal/api/v1/customer/v1/, and {gw-path} stands for organizations/{org}/workspaces/{ws}/applications/{app}/gateways/{gw}. The action column names the grant the operation requires.

Drafts and the two catalogues

Operation Method Path Action
customer.gateways.draft.get GET {gw-path}/environments/{env}/draft gateway.read
customer.gateways.draft.put PUT {gw-path}/environments/{env}/draft config.edit
customer.gateways.draft.history GET {gw-path}/environments/{env}/draft/history gateway.read
customer.gateways.components GET {gw-path}/components gateway.read
customer.gateways.targets GET {gw-path}/environments/{env}/targets gateway.read

draft.get seeds a gateway nobody has edited yet, so it is a read that can write, and it seeds only for a caller who also holds config.edit. The palette names no environment: a card’s availability follows the gateway profile and the caller’s grants.

Explanations

Operation Method Path Action
customer.gateways.inspect POST {gw-path}/environments/{env}/inspect gateway.read
customer.gateways.diff POST {gw-path}/environments/{env}/diff gateway.read

Both are POSTs because a subject and a request description do not belong in a query string. Neither contacts a provider.

Shared policies

Operation Method Path Action
customer.policies.list GET organizations/{org}/workspaces/{ws}/policies gateway.read
customer.policies.get GET organizations/{org}/workspaces/{ws}/policies/{p} gateway.read
customer.policies.publish POST organizations/{org}/workspaces/{ws}/policies/{p}/revisions config.edit
customer.policies.copy POST organizations/{org}/workspaces/{ws}/policies/{p}/copy config.edit
customer.policies.impact GET organizations/{org}/workspaces/{ws}/policies/{p}/revisions/{rev}/impact gateway.read
customer.policies.adopt POST {gw-path}/environments/{env}/draft/adopt config.edit

Publishing appends a revision and moves nobody: each consumer stays pinned until its own draft adopts the new one. The impact report is filtered to the scopes the caller may read, and consumers outside them appear as counts.

Environments

Operation Method Path Action
customer.environments.list GET organizations/{org}/workspaces/{ws}/environments workspace.read
customer.environments.create POST organizations/{org}/workspaces/{ws}/environments workspace.manage
customer.environments.get GET organizations/{org}/environments/{env} workspace.read
customer.environments.update PUT organizations/{org}/environments/{env} workspace.manage
customer.environments.references GET organizations/{org}/environments/{env}/references workspace.manage

The update body carries display_name, state, require_fresh_provider_test and expected_revision. It has no field for selector or protected: both are fixed at creation, and the store’s update statement cannot reach either column.

Releases and deployments

Operation Method Path Action
customer.releases.create POST {gw-path}/environments/{env}/releases config.edit
customer.releases.list GET {gw-path}/environments/{env}/releases gateway.read
customer.releases.get GET {gw-path}/releases/{rel} gateway.read
customer.deployments.deploy POST {gw-path}/environments/{env}/deployments deploy
customer.deployments.rollback POST {gw-path}/environments/{env}/deployments/rollback deploy
customer.deployments.head GET {gw-path}/environments/{env}/deployments/head gateway.read
customer.gateways.promote.review POST {gw-path}/environments/{env}/promotion/review config.edit
customer.gateways.promote.apply POST {gw-path}/environments/{env}/promotion/apply deploy

Creating a release is authoring a pinning under config.edit; deploying one spends money under deploy, and a protected environment adds deploy.protected. A repeated create mints a second release rather than collapsing into the first, so a client that retried a timed-out create lists and compares instead of assuming absorption.

promote.apply states three expectations about the destination, all required, and each one loses with the slug that names what moved. The apply recomputes the plan rather than trusting the caller’s: the caller states expectations and the service states facts.

Member What it echoes Slug when it is stale
expected_mandatory_generation the destination’s required-controls generation at review time mandatory_generation_stale
expected_draft_revision the destination’s current draft revision at review time draft_revision_stale
expected_head_revision the destination’s deployment head revision, 0 for a target nobody has deployed head_revision_stale

They are checked in that order, and the draft revision is settled before anything is derived or deployed. A concurrent edit of the destination therefore loses as draft_revision_stale and never reaches the head.

A release read publishes the release’s identity rather than its document: the revisions it pins, its effective digest, its mandatory generation and its resolved connection bindings. It carries no routes and no model_choices, which is why a client comparing a draft against what is applied calls customer.gateways.diff rather than rendering a release.

Availability. These eight rows are declared in the lane’s registry, and the promotion, release and deployment handlers behind them are landing across this private test. Promotion review and apply, the deployment head read and the diff are the four the shipped portal calls today. A deployment that composes no release ledger answers 503 dependency_unavailable with “deployments not configured” rather than 404, so a wired path and a misspelled one stay distinguishable.

Words a release pins

Seven words carry the lifecycle, and readers get the last three wrong most often.

Term What it means
draft the editable gateway-config/v1 document of one gateway in one environment; saving one reroutes no traffic
draft revision the append-only counter of that document’s saves, echoed back as expected_revision
release one immutable pinning derived from a draft: the settings revision, the derived policy and profile revisions, the mandatory generation, every slot’s connection, and the effective digest
deployment head the one mutable pointer per gateway and environment: desired release, applied release, derived state, and the revision a change must echo
effective digest the compiler’s identity for what will execute, compared between the control plane and the serving cell
mandatory generation the version of the required controls a release was compiled under, detectable later without recompiling
slot an inventory upstream’s name, and the unit a connection binds

Creating a release changes nothing about what a gateway serves; only the deployment head does that. A target nobody has deployed has no head, which is a different fact from a head in draft state.

The digest is why a release cannot drift: the control plane derives and compiles it, the serving cell resolves the same pinned revisions under the same compiler id, and a mismatch is release_digest_mismatch rather than a request served from a guess. The mandatory generation is what makes mandatory_generation_stale and rollback_incompatible answerable. A slot maps to a connection because several models of one upstream share one credential, and an unknown upstream stops the request before dispatch.

What this page does not cover