Pipelines
A pipeline is one sentence: "consolidate all my USDC onto Polygon."
Underneath it is machinery you can configure separately — a sweep policy per source chain, and a bridge policy for the crossing. A pipeline owns none of it. What it adds is the statement that they belong together, which is what lets one screen answer "where is my money and what is it doing" — a question neither half can answer alone.
{
"name": "USDC to Polygon treasury",
"token": "USDC",
"destinationChain": "polygon",
"destinationWalletId": "twl_polygon_main",
"bridgePolicyId": "brp_usdc_polygon",
"sweepPolicyIds": ["swp_eth_usdc", "swp_base_usdc", "swp_avax_usdc"],
"enabled": true
}
Deleting a pipeline deletes the name. The sweep and bridge policies outlive it, because you probably still want those sweeps running.
A source with no route is kept, not rejected
If you add a source chain that cannot reach the destination, the pipeline keeps it — marked unsupported, with the reason attached — and skips it at run time.
That is deliberate. If you sweep USDC on six chains and can bridge from four, you want the four to work and the other two visible, rather than silently dropped from a list you submitted.
The reason is recorded when you add the chain rather than computed on each read, so the answer you were shown when you configured it is the answer you see afterwards — and a route withdrawn later shows up as a change rather than as a silent disappearance.
The whole point of checking routes at configuration time is that you should never discover a gap
by receiving a 422 from a scheduled run. If Circle does not issue USDC on the chain you picked,
the pipeline screen says so while you are still deciding.
Pipelines never chain bridges
There is no search for an indirect path. A source with no direct route to the destination is unsupported, full stop — ChainOS will not route ETH → Base → Polygon around a missing route.
Multi-hop doubles the in-flight window and the failure surface for no benefit you asked for, and the in-flight window is the thing the entire treasury component is organised around minimising.
Running one
POST /v1/treasury/pipelines/{id}/run
Triggers a sweep on each supported source chain and returns as soon as they are planned. ChainOS cannot sign, so the operations then wait for your Edge.
The bridge is not started by a run, and that is deliberate rather than an omission: the sweeps have to confirm before their proceeds exist in the source treasury wallet, and bridging now would burn a balance that has not arrived. The bridge policy's own trigger fires when it has — which is the whole reason the two halves are policies rather than steps in a script.
skipped names every source that was passed over and why: an unsupported route, a paused policy,
or simply nothing to move. A pipeline over six chains where one is quiet is an ordinary Tuesday.
The flow diagram

GET /v1/treasury/pipelines/{id}/flow
Returns the stages left to right, in the order the money travels: deposits, the sweep, the bridge, the destination treasury. Its own endpoint rather than a field on the pipeline, because the configuration changes when somebody edits it and this changes every time money moves.
Each stage carries a state:
| State | Meaning |
|---|---|
idle | Nothing waiting here right now. |
working | Funds are moving through this stage. |
blocked | Something is stopping it — a paused policy, an exhausted funding wallet. |
excluded | This source cannot reach the destination. |
Render excluded in place, greyed, with its detail beside it. A customer who configured a
chain and then cannot find it on the diagram has a worse problem than one who can see why it is
greyed out.