Skip to main content

Request a Config-Target Exception

Tasks

A named-policy exception downgrades one CEL policy's decision. A config-target exception is different: it overlays one of your resolved configuration controllers directly — a model budget cap or an egress domain allowlist — so every policy that reads the resolved, exception-adjusted value sees the change, not just one named policy.

When to use this

Use a config-target exception when a developer is blocked by:

  • A model budget cap (budget.model-cap) and needs a temporary, time-bounded increase to a specific tier's limit.
  • The egress allowlist (network.egress) and needs temporary access to a specific domain.

Both of these already had a read side — a granted exception has always been honored once it exists. What this page covers is how to create one: the request-and-approve flow a developer or an admin actually uses.

For a one-time top-up to a single session's spend cap instead of a durable budget-cap exception, see Grant a session budget top-up — a different mechanism with different durability.

Request an exception

A config-target request reuses the same endpoint as a named-policy exception request (POST /api/v1/sessions/me/request-exception), with controllerID set instead of policyName:

curl -X POST "$WORKSPACE_URL/api/v1/sessions/me/request-exception" \
-H "Authorization: Bearer $SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"target": "config",
"controllerID": "budget.model-cap",
"subject": "claude-opus*",
"scope": "platform-eng",
"justification": "Large one-off migration needs headroom for the rest of the month",
"params": { "amountUSD": 100 }
}'

subject is the model pattern the rule matched (e.g. claude-opus*); scope is the tier the rule applies to (a team name, a user email, or omitted for the org-wide tier); params.amountUSD is the additional USD to add to that tier's limit — it must be a positive number.

justification is always required. policyName is not — omit it for a config-target request; controllerID takes its place. The request is rejected up front (before it reaches the approval queue) if controllerID isn't one of the recognized config controllers, or if the controller-specific fields are missing or invalid (a non-positive amountUSD, an unparseable egress domain pattern) — this is a UX check, not the enforcement boundary; the response body names the problem.

note

From Claude Code or another connected AI tool, use the client's own /request-exception command — it fills in the session token automatically. The curl form above is for scripting or the Builder Portal API.

Approve or deny it

Approval works exactly like a named-policy exception request — see Approve or deny a request for the full walkthrough (single-approver, multi-approver co-sign, and revoke). The request shows its target controller and subject instead of a policy name so you can see what's actually being widened before you decide.

Once approved, the grant is folded into Config Resolution immediately: the developer's next call re-resolves the effective budget limit or egress allowlist with the exception applied. There's no separate "activate" step, and nothing to clean up when it expires — an expired or revoked grant simply stops contributing to the resolved value.

See also