Bruno API Client | Blog & News

Script Execution Flow in Bruno

Written by Ganesh Patil | Oct 8, 2025

When you're building and testing APIs, automation is key. Bruno, as an API client, empowers you to automate your API workflows using powerful JavaScript scripts. But to truly master Bruno's scripting capabilities and write effective, bug-free tests, you need to understand one crucial concept: script execution flow

Bruno offers two distinct ways your scripts can execute during a collection run: the Sandwich Flow and the Sequential (Natural) Flow. Knowing which one to use and how they work will help you write cleaner, more organized, and more efficient scripts.

Let's dive in!

Table of Contents

Understanding Script Execution Flow in Bruno

In Bruno, scripts can be attached at three levels. Each narrower level adds logic specific to that part of the collection:

Collection

Runs for every request in the collection.

Folder

Runs for requests inside that folder.

Request

Runs only for the individual request.

Every level can contain three script types:

1 · Pre-request

Prepare variables, headers, auth, or body before the request is sent.

2 · Post-response

Read the response, extract data, and perform teardown after the API call.

3 · Test

Run assertions and validate the final response state after post-response scripts.

Script Execution Flow: Sandwich vs. Sequential

Bruno provides two modes for how these layered scripts interact during a collection run:

1. Sandwich Flow DEFAULT

The Sandwich Flow is named for how it "sandwiches" the individual request's execution between the collection and folder level scripts. This is the default and most commonly used flow because it ensures all setup (pre-scripts) happens before the request, and all teardown/validation (post-scripts and test scripts) happens after the request, across all layers.

Imagine it like preparing and cleaning up a meal:

  • Collection Pre Script: Prepare the kitchen (global setup).
  • Folder Pre Script: Prepare the table (folder-specific setup).
  • Request Pre Script: Cook the specific dish (request-specific setup).
  • (The Actual Request Executes)
  • Request Post Script: Taste the dish and clean your plate (request-specific teardown).
  • Folder Post Script: Clear the table (folder-specific teardown).
  • Collection Post Script: Clean the kitchen (global teardown).
  • Request Test Script: Rate the dish (request-specific assertions).
  • Folder Test Script: Check the table setting (folder-level assertions).
  • Collection Test Script: Inspect the kitchen (global assertions).

Sandwich execution order

01 · PRECollection
02 · PREFolder
03 · PRERequest
API CALLSend Request
04 · POSTRequest
05 · POSTFolder
06 · POSTCollection
 
07 · TESTRequest
08 · TESTFolder
09 · TESTCollection

Scroll horizontally on smaller screens. Pre scripts move inward; Post and Test scripts move outward.

This flow is ideal for managing authorization tokens, setting global variables, and performing clean-up or assertions that need to happen around the core request logic — from the request level back out to the collection.

2. Sequential (Natural) Flow

The Sequential Flow, also called Natural Flow, executes each phase (pre, post, then test) from the outermost scope to the innermost. It's more of a top-to-bottom batch execution model.

Think of it as preparing all the ingredients, then cooking, then doing *all* the cleaning and inspection from the top down:

  • Collection Pre Script: Gather all kitchen items.
  • Folder Pre Script: Gather all table items.
  • Request Pre Script: Gather all specific dish items.
  • (The Actual Request Executes)
  • Collection Post Script: Clean kitchen.
  • Folder Post Script: Clean table.
  • Request Post Script: Clean specific dish area.
  • Collection Test Script: Inspect kitchen.
  • Folder Test Script: Inspect table.
  • Request Test Script: Inspect the dish.

Sequential execution order

 
COLLECTION
FOLDER
REQUEST
PRE →
01 · Collection Pre
02 · Folder Pre
03 · Request Pre
SEND →
API CALL · Send Request
POST →
04 · Collection Post
05 · Folder Post
06 · Request Post
TEST →
07 · Collection Test
08 · Folder Test
09 · Request Test

Every phase moves in the same direction: Collection → Folder → Request.

While less common for typical API testing, this flow can be useful in specific scenarios where you want each phase — pre, post, and test — to complete from collection → folder → request before moving on.

Which flow should you use?

Choose Sandwich
  • You want nested setup and cleanup.
  • Request-level validation should run first.
  • You prefer Bruno's default behavior.
Choose Sequential
  • You want every phase to run top-down.
  • Collection logic should execute first.
  • Your scripts depend on natural scope order.

Key Rule: Collection-Level Scripts Execute for Each Request

Regardless of whether you're using Sandwich or Sequential flow, there's a crucial rule to remember when running a collection:

One request means one complete script cycle

Any collection-level Pre-request, Post-response, or Test script executes once for every request that runs. The same applies to folder-level scripts for requests inside that folder.

This means if you have 10 requests in a collection and a script at the collection level:

  1. The Collection Pre-request script runs.
  2. Request 1 executes.
  3. The Request 1 Post-response and Test scripts run (along with folder/collection post and test scripts, depending on the flow).
  4. Then, the Collection Pre-request script runs again.
  5. Request 2 executes.
  6. ...and so on for all 10 requests.

This behavior is fundamental for tasks like:

  • Token Management: A collection-level pre-request script can refresh an authentication token before every request if it's expired.
  • Global Setup/Teardown: Performing logging, setting environment variables, or clearing data per request.
  • Automated Assertions: A collection-level test script can check for a common status code or response shape across every request.

How Request-Level Scripts (Pre, Post & Test) Integrate

At the most granular level:

  • Request Pre-request scripts execute before the API call, allowing you to prepare the request body, headers, or URL dynamically.
  • Request Post-response scripts execute after the API call, enabling you to extract data from the response or run teardown logic.
  • Request Test scripts execute after post-response scripts, enabling you to perform assertions and validate the response.

These request-level scripts are where you define the specific setup, teardown, and validation logic unique to each API call, working in concert with the broader collection and folder scripts.

Configuring Script Execution Flow

While the Sandwich Flow is the default behavior, you can explicitly set the desired execution flow (either Sandwich or Sequential) for your collection in your collection configuration.

For Bru collections, set the flow property in bruno.json:

bruno.json
{
  "scripts": {
    "moduleWhitelist": ["crypto", "buffer", "form-data"],
    "filesystemAccess": {
      "allow": true
    },
    "flow": "sequential" // Or "sandwich"
  }
}

For YAML (OpenCollection) collections, set it in opencollection.yml:

opencollection.yml
extensions:
  bruno:
    scripts:
      flow: sequential  # Or "sandwich"

By setting "flow": "sequential", all collection runs for this collection will use the Sequential Flow. If this property is omitted, Bruno will default to the Sandwich Flow.

Quick tip: If your existing collection does not define flow, no change is required as Bruno automatically uses Sandwich Flow.

Conclusion

Bruno's script execution flows, particularly the default Sandwich Flow, provide a powerful framework for organizing your API automation. By understanding when and where each pre-request, post-response, and test script executes, you can write sophisticated tests, manage complex authentication, and streamline your entire API development and testing workflow.

Dive into Bruno's scripting features, experiment with different flows, and build API test suites that are not just functional but also clean, efficient, and robust!

For more detailed examples and advanced use cases, refer to the official Bruno documentation on Script Flow.

Join our Discord server to connect with the Bruno community!