Postman Flows: Visual API Chaining and No-Code Test Workflows

Postman Flows: Visual API Chaining and No-Code Test Workflows
  • Postman Flows is a visual canvas for chaining API requests without writing collection scripts
  • Data passes between blocks using typed connections — no pm.collectionVariables needed
  • Conditional (If) blocks branch the flow based on response values
  • Flows are shareable and runnable inside Postman — no local runtime required
  • Use Flows for orchestration and data pipelines; use scripted collections for CI and assertions

When Scripts Become the Bottleneck

Chaining API calls in a Postman collection works — until it doesn't. Setting a variable in one test script, referencing it in the next request, debugging why the variable is undefined three requests later: the complexity scales poorly, and the logic is invisible unless you read every script in sequence. Postman Flows trades the script-centric model for a visual canvas where data flow between requests is literal — you draw a line from an output to an input, and Postman handles the wiring.

This post explains what Flows is, walks through building a complete workflow, covers conditional logic, and helps you decide when to reach for Flows versus sticking with scripted collections.


What Postman Flows Is

Postman Flows is a node-based, visual workflow builder embedded in Postman. It lets you:

  • Chain API requests so the output of one request feeds into the input of the next
  • Transform and extract data between steps using the built-in FQL (Flows Query Language) expression editor
  • Branch conditionally based on response status codes or body values
  • Loop over lists — run a block for each item in an array
  • Log and display intermediate values for debugging

A Flow lives inside a Postman workspace and can reference any collection in that workspace. You do not write JavaScript to connect steps — you drag connections between typed ports on blocks.

Flows are distinct from collections. They are not exported as JSON and run via Newman. They run inside Postman (cloud or desktop) and are meant for orchestration and data exploration, not CI pipelines.


Building Your First Flow: User Registration Workflow

Let us build a flow that:

  1. Creates a new user via POST /users
  2. Extracts the new user's ID from the response
  3. Fetches the created user via GET /users/{id}
  4. Verifies the fetched user's email matches what was sent

Step 1: Open the Flows Editor

In Postman, open a workspace and click Flows in the left sidebar. Click New Flow. You land on an empty canvas with a Start block on the left.

Step 2: Add a Send Request Block

Drag a Send Request block onto the canvas. In the block's settings:

  • Select the collection: User API
  • Select the request: POST /users

The block now shows input ports on the left (variables you can override) and output ports on the right (response.body, response.status, response.headers).

Step 3: Pass Body Data into the Request

Click the Start block. Add a Create Variable block and set:

{
  "name": "Alice Example",
  "email": "alice@example.com",
  "role": "member"
}

Connect the output of the variable block to the body input port of the POST /users block. When the flow runs, Postman sends this object as the request body.

Step 4: Extract the User ID

From the response.body output port of the POST /users block, drag a connection to a new Select block. In the Select block's expression field, type:

body.id

This extracts id from the response body. The output of the Select block is now the scalar value of the new user's ID.

Step 5: Add the GET Request Block

Add another Send Request block for GET /users/{id}. Connect the Select block's output to the userId path variable input port of this block.

Step 6: Log the Result

Add an Output block and connect the response.body output of the GET request to it. When you run the flow, the Output block displays the fetched user object in the right panel.


Passing Data Between Steps

The typed connection system is the key difference between Flows and scripted collections. In a scripted collection, data sharing looks like this:

// POST /users test script:
pm.collectionVariables.set("newUserId", pm.response.json().id);
// GET /users/{{newUserId}} URL:
{{baseUrl}}/users/{{newUserId}}

In Flows, the same relationship is a drawn line. No variable names to invent, no risk of typos, no debugging undefined because you forgot which scope to set the variable in.

FQL Expressions

When you need to transform data between steps, use FQL (Flows Query Language) — a lightweight expression language for navigating and reshaping JSON:

body.users[0].id                  # first element of an array
body.orders | length              # count items in an array
body.price * 1.2                  # arithmetic
body.status == "active"           # boolean comparison
body.tags | contains("premium")   # array membership

FQL expressions go inside Select or Evaluate blocks between request steps. They are not JavaScript — there are no loops, functions, or side effects. For complex transformation logic, keep using collection scripts.


Conditional Logic in Flows

The If block branches a flow based on a boolean expression. Add an If block after any Send Request block:

  1. Connect the response.status output port to the If block's condition input
  2. In the condition expression, type: response.status == 201
  3. The If block exposes two output ports: True and False

Wire the True output to the next happy-path block. Wire the False output to a Log block that records the error response for debugging.

Example: Conditional Retry Pattern

POST /auth/token
  └─ If: response.status == 200
       True  → extract token → GET /protected-resource
       False → Log: "Auth failed" → Stop

You can nest If blocks. A flow that creates a resource, then conditionally sends a notification only if the resource was created in a specific category:

POST /items
  └─ If: body.category == "premium"
       True  → POST /notifications (send welcome email)
       False → (no notification, continue)
  └─ GET /items/{{body.id}}   (always runs)

Looping Over Arrays

The For block iterates over an array, running all connected downstream blocks once per element. This is the Flows equivalent of a data-driven Newman run, but without a CSV file.

Example: given a list of product IDs, fetch each product and log its price.

  1. Connect to a For block
  2. Inside the For block, add a Send Request block for GET /products/{id}
  3. Connect the For block's item output (one element per iteration) to the productId path variable input
  4. Connect the response body to an Output block

Add a Create Variable block with value:

["prod_001", "prod_002", "prod_003"]

The flow runs the GET request three times, once for each product ID, and displays all three results in the Output panel.


Building a Complete Workflow: Order Processing Pipeline

Here is a realistic e-commerce flow that tests a multi-step business process:

[Start]
  │
  ▼
[Create Variable: order payload]
  {customerId: "cust_123", items: [{sku: "SKU-01", qty: 2}]}
  │
  ▼
[POST /orders]  ──── response.body ────►
  │                                     [Select: body.orderId]
  │                                           │
  ▼                                           ▼
[If: response.status == 201]        [GET /orders/{{orderId}}]
  True ──────────────────────────────────────►│
  False → [Log: order creation failed]        ▼
                                      [If: body.status == "pending"]
                                        True → [POST /orders/{{orderId}}/confirm]
                                                    │
                                                    ▼
                                               [Output: confirmation]
                                        False → [Log: unexpected status]

This flow covers: order creation, ID extraction, order retrieval, status validation, and confirmation — a sequence that would require five inter-dependent collection requests and four pm.collectionVariables.set calls to replicate in a scripted collection.


When to Use Flows vs Scripted Collections

Flows and collections are complementary, not competing.

Scenario Flows Scripted Collection
Visual data exploration Yes No
Onboarding non-developers Yes No
CI pipeline integration No Yes (Newman)
Scheduled monitoring No Yes (Monitors)
Complex assertion logic No Yes
JUnit / HTML reporting No Yes
Looping over a data file No Yes (--iteration-data)
Chaining without scripting Yes No
Sharing with PMs / designers Yes Harder

Use Flows when: you are exploring an unfamiliar API, prototyping a multi-step workflow, or handing a demo to a non-technical stakeholder who needs to run it themselves.

Use scripted collections when: the workflow needs to run in CI, produce structured reports, handle complex assertions, or integrate with test management tooling.

In practice, many teams use both: a Flow to understand and prototype the API behavior, and a scripted collection (derived from the same requests) for automated testing in CI.


Sharing and Running Flows

Flows live in a Postman workspace and are accessible to any workspace member. To share:

  • Within a team workspace: the flow is immediately visible to all members
  • Via a public workspace: make the workspace public; the flow is browsable without a Postman account
  • Via a Run in Postman button: embed a link in documentation that forks the flow into the viewer's workspace

Running a flow is a single click on the Run button in the Flows editor. You can also run a flow via Postman's API (for triggering flows from external systems), though this is less common than triggering collections via Newman.


Wrapping Up

Postman Flows brings API orchestration to the canvas. The visual connection model eliminates variable-passing boilerplate, the If and For blocks handle branching and iteration without scripting, and the result is a workflow anyone on the team can understand and run.

The tradeoff is intentional: Flows trades CI integration and assertion expressiveness for accessibility and clarity. For automated testing pipelines with pass/fail gates and structured reports, scripted collections and Newman remain the right tool. For exploration, documentation, and stakeholder-facing demos, Flows is a genuinely better experience.

Next in this series: moving from API correctness testing to load testing — how Artillery distributes load across a worker fleet and runs serverless on AWS Lambda.

Read more

Start now free