Approval pipelines
Define how requests are evaluated and when they reach human review.
Approval pipelines allow you to write rules to approve requests, deny them or send them for human review.
The Approval pipelines concept explains how they fit into withHuman.
How rules apply
Every request starts in the entry pipeline. Use it for rules that apply to every request. Your organization has exactly one entry pipeline and it can't be archived.
You can create more pipelines, for example one for each team that owns a set of rules. A request only reaches another pipeline when a Delegate block hands it over. A request that is handed over is settled in that pipeline, and nothing after the Delegate block runs.
Loading diagram…
Diagram source
flowchart TD
request["Request from an agent instance"] --> entry["Entry pipeline"]
entry -->|"Approve or deny"| entryDecision["Return decision to the agent"]
entry -->|"Delegate block matches"| delegated["Delegated pipeline"]
entry -->|"Ask a human or no decision"| entryReview["Human review"]
delegated -->|"Approve or deny"| delegatedDecision["Return decision to the agent"]
delegated -->|"Ask a human or no decision"| delegatedReview["Human review"]An approval, denial or human-review outcome stops pipeline processing. If no pipeline decides, the request goes to human review.
Pipelines
Open Approval pipelines from the side menu to find them. The entry pipeline is at the top of the page. Below it is a table of your other pipelines. For each one, the Delegated from column shows which Delegate blocks send requests to it. Filter pipelines searches by name or key, and the status filter can include archived pipelines when there are any.
When a request needs human review and none of your rules says who should review it, it goes to your default reviewers. The If no decision is made card shows who they are. To pick a different escalation path, select Change default reviewers.
If you only manage some pipelines, you see just those.


Creating a pipeline
Select New pipeline, then give it a Name and a Key. Delegate blocks name the pipeline by its key, and permissions can apply to it. You can rename a pipeline later, but you can't change its key, and a key is never reused, even after the pipeline is archived.
A new pipeline starts empty and active, and nothing hands requests to it yet. Add its blocks, then add a Delegate block to the entry pipeline, or to another pipeline, to send requests its way. Until its blocks decide, every request handed to it goes to human review.
To let a team own the pipeline, grant them pipeline permissions for it. See Permissions.
Archiving a pipeline
Select Archive pipeline from a pipeline's action menu. You can't archive the entry pipeline, or a pipeline that an active revision of another pipeline still delegates to. Remove those Delegate blocks and activate the change first.
An archived pipeline keeps its revisions, and requests already being evaluated finish with the rules they started with. It can't be made active again, no pipeline can delegate to it, and its key can't be reused. Archiving can't be undone.
Rules and blocks
A pipeline's rules are made up of blocks. Each block evaluates the request and can approve it, deny it, ask for human review or continue to the next block.
Select Edit pipeline, then Add block. Choose the type based on how the rule makes its decision.
| Block | Use it to |
|---|---|
| Outcome block | End the pipeline with the outcome you choose. Every request that reaches it stops here and gets that outcome straight away, and no later block runs. |
| Webhook block | Ask an external service for an outcome. |
| AI Judge block | Let an AI model decide the request against a policy you write in plain language. Hosted edition only. |
| Branch | Run a set of blocks only for requests that match a condition. |
| Delegate to pipeline | Hand requests that match a condition to another pipeline. |
Branch and Delegate blocks choose requests with conditions on the request's fields. See Conditions for the available fields and comparisons.
Webhook blocks reference shared Webhook endpoints, which manage the external service's destination and signing secret separately from the pipeline.
Blocks run in their configured order and stop at the first approval, denial or human-review outcome. Their order matters: a block can't check a request that an earlier block has already decided.
A Branch block holds its own blocks and runs them only for requests that match its condition. Other requests skip it. A request that enters a branch finishes there: if none of its blocks decides, the request goes to human review and nothing after the branch runs.
Give each block a name that explains its rule. Drag blocks to reorder them. Their action menus also move, duplicate or remove them, including moving them into and out of branches.
Build your rules around the information in the request. Check the tool name when a rule should apply only to a particular tool.
The JSON editor is another way to edit the same pipeline; the examples here use the visual Blocks editor.
Tool and argument suggestions
Tool-name suggestions come from your agents' Tools catalogues, supplemented by recent requests you can read. You can build a rule before a discovered tool has sent its first request. Descriptions, sources and schema variants help you choose the right name.
Start with Tool name set to equals or in. Argument suggestions then follow the possible tools in that condition group. Separate alternatives keep their own suggestions. Fields that apply to only some tools are labeled, and conflicting types remain visible.
A name condition matches every source that sends that name. It cannot distinguish two servers exposing the same approval name. Gateway suggestions use the name in approval requests, which can differ from the server-prefixed name advertised to the agent.
Choose an argument to see suitable comparisons and value suggestions. Numbers and booleans have typed controls; enums offer the schema's allowed values. All operators and manual names or paths remain available. Use the JSON editor for array-element predicates; the field picker does not generate wildcard paths. Complex schemas remain available in the agent's tool details, and external schema references are not fetched.
Warnings identify saved fields or comparisons that conflict with current definitions. They are advisory: a refresh never rewrites, deactivates or changes execution of your saved pipeline. When a schema is missing or incomplete, use manual conditions and test them with a representative request.
Example: Refund rules
Our Support assistant calls issue_refund, with amount in dollars and currency set to USD. We want the $500 limit to apply to every agent, so that rule belongs in the entry pipeline. The rules for smaller refunds belong to a Support pipeline that our support team owns.
We'll add these blocks, in order.
| Pipeline | Block | When | What it does |
|---|---|---|---|
| Entry | Branch Deny refunds over $500 | Amount greater than 500 | An Outcome block denies the refund. |
| Entry | Delegate Support assistant requests | Agent slug equals support-assistant | Continues in the Support pipeline. |
| Support | Branch Approve refunds up to $20 | Amount at most 20 | An Outcome block approves the refund. |
| Support | Branch Review refunds over $20 | Amount greater than 20 and at most 500 | An Outcome block asks a human, using Payments review. |
Each refund branch will also check that Tool name equals issue_refund and currency equals USD. We'll use All so the tool, currency and amount conditions must all match. That keeps these rules specific to USD refunds.


Outcome blocks
Use an Outcome block to catch every request that earlier blocks have passed on. Select Add block, then Outcome block. Give it a name and reason, and choose Approve automatically, Deny automatically, or Ask a human. New Outcome blocks start with Ask a human. You can select an escalation path or inherit the pipeline default.
For example, put a branch that approves small refunds first, followed by an Outcome block named Review everything else. Choose Ask a human and your review path. Every request that reaches that block goes to those reviewers, including requests for other tools.
An Outcome block stops the pipeline. Blocks below it stay editable and show Unreachable, naming the Outcome block that prevents them running. Move or remove the Outcome block to let later blocks run. These warnings do not prevent saving or activating a valid revision. Unreachable blocks still undergo the same validation as every other block.
In the entry pipeline, an Outcome block outside any branch also decides the requests that a Delegate block below it would have handed over. Inside a branch, an Outcome block decides only the requests that match the branch; see Branch blocks.
The fallback card remains editable even when it is unreachable. Its default escalation path still applies to human outcomes that inherit it. If you have no Outcome block and no earlier block decides, requests still go to human review.
Human review
An Escalation path decides who is contacted and when a request needs human review. Select one on a block to use it for that block's human-review outcomes, or choose a default escalation path for the pipeline.
withHuman uses the first available option in this order.
- The escalation path chosen on the block that asked for a human. When no block in a branch decides, that's the branch's escalation path.
- The default escalation path of the pipeline the request was in.
- The default escalation paths of the pipelines that handed the request over, starting with the nearest and ending with the entry pipeline.
- Any authorized reviewer, if no path is selected.
The defaults also apply when all blocks finish without a decision. Blocks inside a branch don't inherit the branch's escalation path: one that asks for a human without its own path uses the defaults. Routing a request to someone doesn't replace their permission to decide it. See Escalation paths for how reviewers are contacted.
The agent's owner
Some agents are run by one person for themselves, such as a coding agent on a laptop. You can send their requests to the person who runs them instead of to a team. Wherever you choose an escalation path, choose The agent's owner. Under If the agent has no owner, keep Pipeline default or choose a path.
- The owner is notified through their own notification settings, and only they can decide the request. It waits for them until they decide or it expires; it never moves on because they haven't answered.
- Requests from agents without an owner, such as a support bot your organization runs, go to the fallback straight away: the path you chose, or else the pipeline default. So do requests whose owner is suspended or doesn't have permission to approve requests. With no default path either, any authorized reviewer can decide them.
- If the owner is suspended or removed while a request is waiting, the fallback path takes the request over.
- A block that chooses its own escalation path doesn't ask the owner, even when the pipeline default does.
You don't need an escalation path to use it. The guided setup sets up your coding agents this way, with a path to you as the fallback. People can always approve their own agents' requests when routing reaches them.
Example: Payments review
Our refunds need the Payments team, even if other requests use a different default path. We'll select Payments review directly on the Outcome block in Review refunds over $20. That choice takes precedence over the pipeline defaults.
Pipeline testing
Test request evaluates a sample against your rules, including unsaved changes to the pipeline you're editing. Open it from the Approval pipelines page or a pipeline's action menu and enter a sample request.
Where the test starts depends on where you open it.
- The Approval pipelines page. The test starts in the entry pipeline, just like a real request.
- A pipeline's page. The test starts at that pipeline's first block. Pipelines that hand requests to it don't run.
When the sample matches a Delegate block, the test continues in the pipeline it names, using that pipeline's active rules. The Delegate block shows what that pipeline decided. Open the pipeline to see its own blocks.
The highlighted blocks show the route the sample takes, including which branches it entered or skipped. Read each block's outcome and reason to see why it continued or stopped. Later blocks are skipped after a final outcome, and a failed block shows its error.
Testing doesn't create an approval request or contact reviewers. It does make real calls to AI Judge models and webhook endpoints, so use sample data and an endpoint suitable for testing.
Example: A $75 refund
First, we'll save and activate the Support pipeline so the test includes it. Then we'll select Test request on the Approval pipelines page with this $75 request.
{
"request": {
"tool": "issue_refund",
"arguments": { "amount": 75, "currency": "USD" },
"agent_reasoning": "The customer was charged twice for the same order."
},
"agent": { "slug": "support-assistant", "name": "Support assistant" }
}The request passes the $500 limit and is handed to the Support pipeline. It doesn't match the small-refund approval there, so it reaches Payments review. Changing just the amount shows which rule makes each decision.
| Amount | Expected result |
|---|---|
| $10 | The Support pipeline approves it. |
| $75 | The Support pipeline sends it to Payments review. |
| $600 | The entry pipeline denies it before the Support pipeline runs. |


Drafts and activation
Each saved version of a pipeline is a revision. Only one revision is active at a time. The others remain available in its history.
Create revision saves the rules you're editing. Keep as draft leaves the active rules in place; Make active replaces them with the revision you just saved. Unsaved edits aren't a saved draft.
Editing normally starts from the latest saved revision, which may be newer than the active one. Check the revision label before changing existing rules.
Activation affects new requests. Requests already being evaluated keep their existing rules, and requests waiting for a reviewer aren't evaluated again.
Any escalation paths, webhook endpoints and pipelines the revision references must be active. Pipelines can't delegate to each other in a circle. If activation fails, the saved revision remains available as a draft.


Revision history and rollback
Revisions shows the pipeline's saved history. A revision's action menu lets you View its rules or Create new revision from this to use them as the starting point for an edit.
Use Activate for a newer saved revision or Roll back for an earlier one. Both change which revision handles new requests. Rolling back keeps the newer revisions in the history.
To remove all checks from a pipeline, remove its blocks and activate the empty revision. An empty entry pipeline sends every request to your default reviewers. An empty delegated pipeline sends every request handed to it for human review.
For a real request, use the Audit log to see which revisions and blocks ran and what they decided.


Permissions
Permissions can apply to the whole organization or to particular pipelines. Access to one pipeline doesn't include the entry pipeline or any other pipeline. To let a team own a pipeline, grant them these permissions for that pipeline.
| Permission | What it lets you do |
|---|---|
pipeline.read | View pipelines and their revisions. |
pipeline.write | Edit, save and test pipeline revisions. With Organization scope, also create pipelines. |
pipeline.activate | Activate revisions, including rolling back to an earlier one, and archive pipelines. |
Viewing escalation paths and webhook endpoints needs access to those resources too. Editing and activation are separate permissions, so someone can save a draft for a colleague to make active.