Flows
Chain saved requests on a canvas, branch and loop, run from the app or the terminal, and load test.
Flows
A flow chains saved requests and the steps between them on a canvas. Each node's output is the next node's input, so a value from one response (a token, an id, a link from a mail) can fill the next request. Flows are saved in the workspace like requests and mocks, and run from the app or the bifurc command.
Build a flow
- Open Flows in the sidebar and create a flow
- Use Add node to put nodes on the canvas
- Drag from a node's output port (Success, Error, True, False…) to the next node's input to connect them
- Pick the saved request each request node sends, and fill the values each node needs
- Press Run
Each node shows Done or its error as the run reaches it, and the toolbar says whether the run succeeded and how long it took. A node's Input, Output and Tests tabs show what it received, what it produced and which tests passed.
You can also build a flow from real traffic: in Capture, tick two or more exchanges and choose Create flow. They are saved as requests and chained in the order they were captured.
Nodes
| Node | What it does | Leaves by |
|---|---|---|
| Start | Where a run begins; holds the flow's inputs | Next |
| Request | Sends a saved request, with its scripts and tests | Success, Error |
| Stream | Sends to an SSE, WebSocket, Socket.IO or gRPC stream and reads its messages | Message, Closed, Error |
| MCP | Calls a tool or prompt, or reads a resource, of an MCP request | Success, Error |
| Waits for the matching mail of this run in the local mail inbox and hands on its code and link | Success, Error | |
| If | A JavaScript expression over the input and variables | True, False |
| Condition | Named branches, each a set of rules on the input | Each branch, Else |
| Validate | Rules the input must pass | Pass, Error |
| Evaluate | A JavaScript expression whose value is the output | Out, Error |
| Repeat / For each | Runs the nodes after it a number of times, or once per item of a list | Each, Done |
| Delay | Waits before going on | Out |
| Or | Goes on when any one of its inputs arrives | Out |
| Data / Sample | A constant JSON value | Out |
| Display | Shows its input in the app | Out |
A request node fails on a non-2xx answer by default, and can retry. Text fields can use {{input.body.id}} (what the node before produced), {{nodes.<id>.headers.location}} (what an earlier node did), {{flow.<input>}} (an input of the run) and your environment's variables.
Run from a terminal
bifurc flows list
bifurc flows run "Checkout" --input email=maya@acme.dev --env staging
bifurc flows run "Checkout" --fresh-session --verbose
run prints one line per step and then flow passed · 5 steps · 166ms or the step that failed, and exits 1 when the run or a test fails. --fresh-session gives the run a cookie jar of its own.
A straight line of requests can be written as YAML steps:
name: Checkout happy path steps: - request: Login as admin - request: Create cart extract: { cartId: .id } - request: Add item vars: { qty: 2 } expect: [ status == 201, .items | length == 1 ] - mail: { to: "{{email}}", timeout: 30s, extract: { otp: otp } }
bifurc flows create --steps checkout.yaml
Load testing
Set Instances above the canvas to more than one, or use the terminal, to run a flow many times at once:
bifurc flows loadtest "Checkout" --instances 100
The report says how many instances passed and failed, how long an instance and each node took, and what failed how.
Good use cases
- testing a sign-up or checkout from the first request to the confirmation mail
- logging in once and reusing the token in every request after it
- checking how a path holds up with many users at once