Bruno sends API requests from collections stored as ordinary files in a chosen folder. A collection keeps request definitions and environments beside its scripts and tests. The same collection can run in the desktop interface or through the collection runner. The bru command can run it outside the desktop interface. Bruno then displays the response returned by the target endpoint.
Creating a collection requires a storage format and a folder. Bruno writes collection data as YAML or BRU files. The folder can live inside a Git repository, which puts request definitions and their configuration into the same file-based workflow as other project material. Bruno accepts HTTP and GraphQL requests. It also handles gRPC and WebSocket calls. A cURL definition can enter the collection as another request type.
A request inherits values from several places
A request can place variables in its URL or headers. Authentication fields and the body can use them too. Bruno resolves a repeated name through an exact precedence order: runtime, request, folder, environment, collection, then global. A request-level value therefore overrides an environment value with the same name. Selecting another environment does not displace a value that exists in a higher scope.
The storage location changes with the scope. Collection, folder, request, and environment values live in their respective collection files. Runtime and global values use local storage. Prompt variables are never stored, while process environment values come from a separate .env file. The Console can display the resolved value when two scopes appear to disagree.
Scripts can change the call before Send
A pre-request script can set a header or replace the body before Bruno opens the connection. It can also calculate a variable. A post-response script then inspects the returned data, while an assertion can check the status. The CLI uses its safe sandbox by default and has a developer sandbox for code that needs broader access.
Collection scripts introduce a recursion trap. If a collection-level script calls bru.runRequest(), the invoked request can trigger the same collection script again. Repeating that path creates an infinite loop. The loop comes from the collection hook invoking another request that runs the collection hook again.
The runner exposes execution order
The Collection Runner executes selected requests one by one. Each selection remains a request inside the collection while the runner advances through the chosen set. The runner therefore gives Bruno a multi-request execution path through the same file-backed collection.
The bru command runs a collection from the folder that contains bruno.json. It can select a named environment or stop at the first failure. A tag filter limits which requests run. The --tests-only option runs only requests that contain tests or active assertions. Iteration data can repeat the collection with external values. Bruno also exposes safe and developer sandbox modes in the CLI, and safe mode is the default.




