Skip to content

Building flows

A flow is a chain of API steps you can run on demand — from the UI, the CLI, the API, or CI. You build flows on a visual canvas: drag nodes from the palette, connect them with edges, then press Run flow. Each run is recorded as an execution in Run history.

The palette has exactly three node types:

NodeWhat it does
RequestSends an HTTP request. Configure method, URL, headers, and body. Attach outputs and assertions to its response.
DelayWaits for a fixed duration before the next node runs. Useful when the API you are testing settles asynchronously.
ModuleRuns another flow as a child execution step. This is flow reuse: pass values in with input bindings, read values back with output bindings.

A checkout-smoke flow for a payments API might look like:

  1. POST /auth/token — Request node, asserts statusCode equals 200
  2. POST /payments — Request node, extracts $.id into payment_id
  3. Delay 2s — Delay node, waits for settlement
  4. verify-refund — Module node that runs a shared refund-check flow

Edges connect nodes along success or error paths, so a failing request can route to different downstream steps than a passing one.

Each node also has a run_when condition:

  • on_success (default) — the node runs only when its upstream path succeeded.
  • always — the node runs even after an upstream failure. Use this for cleanup steps, such as deleting the test payment a failed run left behind.

Nodes that do not run are marked skipped, and the execution records a skip_reason plus any missing_inputs, so you can see exactly why a step was bypassed.

Reference values anywhere in a request with {{double_brace}} syntax:

Everything on the canvas can also be scripted with the CLI. Add each node type with echopoint flows node add:

Terminal window
# Request node
echopoint flows node add <flow-id> --type request --name "Create payment" \
--method POST --url "{{BASE_URL}}/payments" \
--headers '{"Authorization": "Bearer {{API_TOKEN}}"}' \
--body '{"amount": 4200, "currency": "eur"}'
# Delay node (duration in milliseconds)
echopoint flows node add <flow-id> --type delay --name "Wait for settlement" \
--duration 2000
# Module node: run another flow as a child step
echopoint flows node add <flow-id> --type module --name "verify-refund" \
--flow-id <child-flow-id> \
--input payment_id={{payment_id}} \
--output refund_status=refund_status

Connect nodes with edges, or let --after wire the edge for you when adding a node:

Terminal window
echopoint flows edge add <flow-id> --from create-payment --to verify-refund
# A cleanup step that runs even when upstream failed
echopoint flows node add <flow-id> --id cleanup --type request \
--run-when always --after verify-refund \
--name "Delete test payment" --method DELETE \
--url "{{BASE_URL}}/payments/{{payment_id}}"

Before running a flow in CI, check that its structure is sound — every referenced node exists, bindings resolve, edges connect real nodes:

Terminal window
echopoint flows validate <flow-id>

Export the full flow definition as JSON to review it or keep a copy alongside your code:

Terminal window
echopoint flows export <flow-id>