Use case
How to restrict which AI models one workflow can use
Not every model in your stack should be reachable from every workflow, and a redirect is not a refusal.
Give the workflow its own x-agent-id, then create a model_block policy (or a set of model_allow entries) with scope: { agent_id } set to that id. A call from that workflow that names a disallowed model, or would be served one after a reroute, is refused with HTTP 403 before it reaches the provider. Leave the scope off and the same policy applies to the whole account.
How Spendline does this
Policies are checked in the same request path as budgets, but they answer a different question: not "can this scope still spend money" but "is this specific model allowed here at all." A policy carries the same scope object a reroute rule does (agent_id, customer_id, agent_name), so one vocabulary covers both engines. A scoped policy applies to calls attributed to the agent or customer it names, and also to calls that carry no attribution at all: attribution is a header the caller sets, so a missing header is never a way around a refusal. A call attributed to a different agent is untouched. Both the requested model and the served model are judged, so a reroute cannot make forbidden traffic legal in either direction.
Why it matters
A budget cap alone would let a workflow spend its entire allowance on the single most expensive model available, if nothing stops that model from being chosen in the first place. A reroute can steer it to a cheaper model, but the call still runs and still costs money. A scoped block or allow-list is the control that refuses the model for exactly the workflow in question, without touching the rest of the account.
Frequently asked questions
What does a blocked call return?
HTTP 403, before the request reaches the provider, the same pre-call enforcement pattern as a budget refusal, just checking model identity instead of remaining spend. The body carries code: model_blocked or code: model_not_allowed, the policy that refused it, its scope, and for an allow-list the models that would have passed.
Can I scope this to one workflow instead of the whole account?
Yes. Set scope: { agent_id } on the policy to the workflow's x-agent-id, or scope: { customer_id } to restrict one customer. Calls from that workflow are refused; calls attributed to any other agent are not. Calls with no attribution at all are held to every scoped policy on the account, so a workflow cannot dodge its rules by leaving the header off.
Can I allow only a named list of models instead of blocking one?
Yes. Create one model_allow policy per permitted model (prefix and substring matching let one entry cover a family). Every entry sharing the same scope forms one list, and a call has to match some entry of every list that applies to it. A scoped list narrows what the account list permits; it never widens it.
What happens when a scoped block and a reroute disagree?
The block wins. If a reroute would deliver a workflow to a model its scoped block forbids, the call is refused on the served model. If the workflow asks for a banned model and a reroute would have moved it to an allowed one, the call is still refused on the requested model. A routing rule is never a way to make forbidden traffic legal.
See where this stands in your own setup
This page describes the mechanism. The 5 minute assessment scores your own attribution, enforcement, and reconciliation setup, so you know exactly which of these problems you actually have today.
Run the 5 minute assessment