Skip to main content

Overview

Bruno collections are directories containing .bru files. Collections can have:
  1. collection.bru - Collection-level settings and scripts
  2. folder.bru - Folder-level metadata files
  3. Environment files - Variable definitions for different environments

Collection Structure

my-collection/
├── collection.bru          # Collection settings (optional)
├── environments/
│   ├── dev.bru            # Development environment
│   ├── staging.bru        # Staging environment
│   └── prod.bru           # Production environment
├── users/
│   ├── folder.bru         # Folder metadata
│   ├── get-user.bru       # Individual requests
│   ├── create-user.bru
│   └── delete-user.bru
└── auth/
    ├── folder.bru
    ├── login.bru
    └── logout.bru

Collection File

The collection.bru file defines collection-level settings that apply to all requests.

Basic Collection

headers {
  x-api-version: 1.0
  user-agent: Bruno/1.0
}

auth {
  mode: bearer
}

auth:bearer {
  token: {{collectionToken}}
}

vars:pre-request {
  baseUrl: https://api.example.com
  apiVersion: v1
}

script:pre-request {
  console.log('Collection pre-request script');
}

script:post-response {
  console.log('Collection post-response script');
}

tests {
  test("Collection-level test", function() {
    expect(res.getStatus()).to.be.below(500);
  });
}

docs {
  # My API Collection
  
  This collection contains all endpoints for the Example API.
}

Collection Blocks

Headers applied to all requests in the collection:
headers {
  x-api-version: 1.0
  x-client-id: bruno-client
  accept: application/json
}
Default authentication mode for the collection:
auth {
  mode: bearer
}
Supported modes: none, basic, bearer, digest, awsv4, oauth2, wsse, apikey
Authentication credentials for the collection:
auth:bearer {
  token: {{token}}
}

auth:basic {
  username: {{username}}
  password: {{password}}
}
Variables set before each request:
vars:pre-request {
  baseUrl: https://api.example.com
  timestamp: {{$timestamp}}
}
Variables extracted after each response:
vars:post-response {
  lastRequestId: $res.body.requestId
}
Script executed before each request:
script:pre-request {
  const timestamp = Date.now();
  bru.setVar('timestamp', timestamp);
}
Script executed after each response:
script:post-response {
  if (res.getStatus() === 401) {
    console.log('Authentication required');
  }
}
Tests run for all requests:
tests {
  test("Status should not be 5xx", function() {
    expect(res.getStatus()).to.be.below(500);
  });
}
Collection documentation:
docs {
  # API Collection
  
  Collection description and usage notes.
}

Complete Collection Example

headers {
  accept: application/json
  x-api-version: 2.0
  x-client-name: bruno
}

auth {
  mode: bearer
}

auth:bearer {
  token: {{authToken}}
}

vars:pre-request {
  baseUrl: https://api.example.com
  apiVersion: v2
  defaultTimeout: 30000
}

vars:post-response {
  lastResponseTime: $res.responseTime
  lastStatus: $res.status
}

script:pre-request {
  const timestamp = Date.now();
  const requestId = crypto.randomUUID();
  
  bru.setVar('timestamp', timestamp);
  bru.setVar('requestId', requestId);
  
  console.log(`[${requestId}] Starting request at ${timestamp}`);
}

script:post-response {
  const status = res.getStatus();
  const time = res.getResponseTime();
  
  console.log(`Response: ${status} in ${time}ms`);
  
  // Handle token refresh
  if (status === 401) {
    console.warn('Authentication token expired');
  }
  
  // Store response metadata
  bru.setVar('lastResponseStatus', status);
}

tests {
  test("Response should be successful", function() {
    const status = res.getStatus();
    expect(status).to.be.at.least(200);
    expect(status).to.be.below(400);
  });
  
  test("Response should be timely", function() {
    expect(res.getResponseTime()).to.be.below(5000);
  });
  
  test("Content-Type should be JSON", function() {
    const contentType = res.getHeader('content-type');
    expect(contentType).to.include('application/json');
  });
}

docs {
  # Example API Collection
  
  Complete API collection for Example.com services.
  
  ## Authentication
  All requests require a Bearer token. Set `authToken` in your environment.
  
  ## Rate Limiting
  - 1000 requests per hour per token
  - 100 requests per minute per token
  
  ## Base URL
  - Production: https://api.example.com
  - Staging: https://staging-api.example.com
  - Development: http://localhost:3000
  
  ## Support
  For issues, contact [email protected]
}

Folder Files

The folder.bru file contains metadata for organizing requests within folders.
meta {
  name: User Management
  seq: 5
}
name
string
required
Display name for the folder
seq
number
Sequence number for ordering folders

Folder Example

meta {
  name: Authentication Endpoints
  seq: 1
}

Environment Files

Environment files define variables for different environments (dev, staging, production).

Environment File Location

Environment files are stored in the environments/ directory:
collection/
└── environments/
    ├── dev.bru
    ├── staging.bru
    ├── prod.bru
    └── local.bru

Environment File Format

vars {
  baseUrl: https://api.example.com
  apiKey: your-api-key-here
  timeout: 30000
  debugMode: false
}

Environment Variables

Do not commit sensitive data like API keys or passwords to version control. Use local environments or secret management.

Development Environment

vars {
  baseUrl: http://localhost:3000
  apiKey: dev-api-key
  dbHost: localhost
  dbPort: 5432
  debugMode: true
  logLevel: debug
}

Staging Environment

vars {
  baseUrl: https://staging-api.example.com
  apiKey: {{STAGING_API_KEY}}
  dbHost: staging-db.example.com
  dbPort: 5432
  debugMode: true
  logLevel: info
}

Production Environment

vars {
  baseUrl: https://api.example.com
  apiKey: {{PROD_API_KEY}}
  dbHost: prod-db.example.com
  dbPort: 5432
  debugMode: false
  logLevel: error
  enableCaching: true
  cacheTimeout: 3600
}

Variable Precedence

Variables are resolved in the following order (highest to lowest priority):
  1. Request variables - Set in vars:pre-request within the request
  2. Environment variables - Set in the active environment file
  3. Collection variables - Set in collection.bru
  4. Built-in variables - System variables like {{$uuid}}
Request-level variables override environment and collection variables.

Variable Syntax

Enabling/Disabling Variables

vars {
  enabled_var: value
  ~disabled_var: value
}
Disabled variables (prefixed with ~) are not applied.

Local Variables

Variables prefixed with @ are local and not persisted:
vars:pre-request {
  apiKey: {{API_KEY}}
  @temporaryToken: generated-token
}

Referencing Environment Variables

vars {
  apiUrl: https://{{API_HOST}}/api
  secretKey: {{SECRET_KEY}}
}
Environment variables in {{}} are resolved from:
  • Process environment variables
  • .env files
  • System environment

OAuth 2.0 Configuration

Collections can define OAuth 2.0 authentication with additional parameters:

OAuth 2.0 Authorization Request

auth:oauth2:additional_params:auth_req:headers {
  x-custom-header: value
}

auth:oauth2:additional_params:auth_req:queryparams {
  custom_param: value
}

OAuth 2.0 Access Token Request

auth:oauth2:additional_params:access_token_req:headers {
  x-tenant-id: {{tenantId}}
}

auth:oauth2:additional_params:access_token_req:queryparams {
  scope: extended
}

auth:oauth2:additional_params:access_token_req:body {
  custom_claim: value
}

OAuth 2.0 Refresh Token Request

auth:oauth2:additional_params:refresh_token_req:headers {
  x-refresh-source: bruno
}

auth:oauth2:additional_params:refresh_token_req:queryparams {
  grant_type: refresh_token
}

auth:oauth2:additional_params:refresh_token_req:body {
  client_info: bruno-client
}

Complete Collection Setup

Directory Structure

api-collection/
├── collection.bru
├── environments/
│   ├── dev.bru
│   ├── staging.bru
│   └── prod.bru
├── auth/
│   ├── folder.bru
│   ├── login.bru
│   ├── logout.bru
│   └── refresh-token.bru
├── users/
│   ├── folder.bru
│   ├── list-users.bru
│   ├── get-user.bru
│   ├── create-user.bru
│   ├── update-user.bru
│   └── delete-user.bru
└── posts/
    ├── folder.bru
    ├── list-posts.bru
    ├── get-post.bru
    ├── create-post.bru
    └── delete-post.bru

collection.bru

headers {
  accept: application/json
  content-type: application/json
  user-agent: Bruno API Client
}

auth {
  mode: bearer
}

auth:bearer {
  token: {{authToken}}
}

vars:pre-request {
  requestId: {{$uuid}}
  timestamp: {{$timestamp}}
}

script:pre-request {
  const env = bru.getEnvName();
  console.log(`Running in ${env} environment`);
}

tests {
  test("Status should be valid", function() {
    expect(res.getStatus()).to.be.at.least(200);
  });
}

environments/dev.bru

vars {
  baseUrl: http://localhost:3000
  authToken: dev-token-12345
  apiKey: dev-api-key
  debugMode: true
}

environments/prod.bru

vars {
  baseUrl: https://api.example.com
  authToken: {{PROD_AUTH_TOKEN}}
  apiKey: {{PROD_API_KEY}}
  debugMode: false
}

auth/folder.bru

meta {
  name: Authentication
  seq: 1
}

users/folder.bru

meta {
  name: User Management
  seq: 2
}

Best Practices

Use Environments

Create separate environments for dev, staging, and production with appropriate base URLs and credentials.

Secure Secrets

Never commit sensitive data. Use environment variable references like {{SECRET_KEY}} and .env files.

Collection Scripts

Use collection-level scripts for common logic like authentication, logging, and error handling.

Organize Folders

Group related requests in folders with descriptive names and sequence numbers.

Tips

Use collection-level headers for common headers like accept, user-agent, and API versioning.
Set base URLs in environment variables to easily switch between environments.
Use collection-level tests to validate common requirements like response times and status codes.

See Also

Bru Syntax

Complete Bru language syntax reference

Request Format

Request file format specification

Build docs developers (and LLMs) love