Bruno is a lightweight, Git-native, open-source API client. It is fast, simple to version, and useful for request testing, but it does not include a mock server. If you need to mock endpoints before the backend exists, you need either an external mock tool, a custom stub server, or a spec-driven mock generated from OpenAPI.
Short answer: Bruno has no built-in mock server. You can send requests and write assertions, but you cannot turn a saved request into a fake endpoint that returns sample responses. To mock APIs in a Bruno-style workflow, you need to run something outside Bruno.
Why you need a mock server
A mock server returns predictable responses for endpoints that are not implemented, unstable, or hard to reproduce on demand.
Use one when you need to:
- Build a frontend or mobile app before the backend is ready
- Test error paths such as
429,500, or malformed JSON - Demo a product flow without a live backend or credentials
- Keep CI stable without depending on staging availability
- Reproduce edge cases with controlled response bodies and headers
Common scenarios:
| Scenario | What the mock returns | Why it’s hard otherwise |
|---|---|---|
| Rate limit hit |
429 + Retry-After header |
Backend rarely throttles on demand |
| Server outage |
500 / 503
|
Can’t break staging just to test |
| Slow response | Delayed body | Hard to reproduce real latency |
| Empty result set |
200 with []
|
Depends on specific data state |
| Malformed payload | Body missing a required field | Backend validation usually prevents it |
Does Bruno have a mock server?
No. Bruno focuses on:
- Sending API requests
- Organizing collections as plain files
- Running tests and assertions
- Supporting Git-based collaboration
It does not include a native mock server. There is no setting that turns a Bruno request into a live stub endpoint.
That means Bruno users usually mock APIs in one of two ways.
Option 1: Add an external mock tool
You can run a separate mock server with tools such as:
- Mockoon
- WireMock
- Prism
- json-server
The workflow looks like this:
- Define your mock routes in the external tool.
- Configure mock responses, status codes, and headers.
- Start the mock server locally or in a shared environment.
- Point Bruno requests to the mock server URL.
Example request target:
http://localhost:3001/users/123
Then your Bruno request uses that base URL instead of the real API.
This works well for small local mocks. The downside is that your API contract, Bruno collection, and mock definitions can become separate sources of truth.
Option 2: Write a small stub server
For quick tests, you can hand-roll a mock server.
Example with Express:
import express from "express";
const app = express();
app.get("/users/:id", (req, res) => {
res.json({
id: req.params.id,
name: "Jane Doe",
email: "jane@example.com",
created_at: "2026-06-01T12:00:00Z"
});
});
app.get("/rate-limited", (req, res) => {
res.set("Retry-After", "60");
res.status(429).json({
error: "Too many requests"
});
});
app.listen(3001, () => {
console.log("Mock API running on http://localhost:3001");
});
Then point Bruno at:
http://localhost:3001
This is fast for one or two endpoints. It becomes harder to maintain when your API grows, because you need to keep response bodies, status codes, and schemas in sync manually.
The cost of bolt-on mocking
Adding a separate mock layer works, but it creates maintenance overhead:
- Drift: Your OpenAPI spec, Bruno requests, and mock responses can diverge.
- Setup tax: Every teammate needs to install and configure the mock tool.
- Manual response writing: You have to create sample payloads for every endpoint and status code.
- Static data: Many stubs return the same placeholder data every time.
- Extra review surface: API changes must be updated in multiple files or tools.
For a broader comparison, see the Bruno alternative all-in-one API platform breakdown.
Generate a mock server from your OpenAPI spec instead
A cleaner approach is to generate the mock server from the API contract you already maintain.
Apidog can import or define an OpenAPI spec and generate a working mock server from the same definitions used for design, testing, and docs.
This gives you one source of truth instead of maintaining mocks separately.
With a spec-driven mock, you can:
- Generate mock responses from schemas
- Return data shaped like the real API contract
- Test endpoints before backend implementation
- Share mock URLs with frontend, mobile, and QA teams
- Update mocks automatically when the spec changes
Apidog reads field names and types from the spec. For example, fields like email, created_at, and id can return more realistic values than static placeholders like "string".
Because the mock, request library, and documentation come from the same project, you reduce the chance of drift. If your workflow is Git-centric, the spec can still remain diffable and reviewable, which fits well with a Git-native API workflow. For more practical examples, see API mocking use cases.
Quick how-to: generate a mock URL from OpenAPI
Here is the implementation flow.
1. Prepare your OpenAPI file
Start with an existing OpenAPI or Swagger file.
Example:
openapi: 3.0.3
info:
title: User API
version: 1.0.0
paths:
/users/{id}:
get:
summary: Get user by ID
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
"200":
description: User found
content:
application/json:
schema:
type: object
required:
- id
- name
- email
properties:
id:
type: string
example: usr_123
name:
type: string
example: Jane Doe
email:
type: string
format: email
example: jane@example.com
created_at:
type: string
format: date-time
2. Import the spec
Import the OpenAPI file into Apidog, or point Apidog to the spec URL.
The endpoints, parameters, request bodies, response schemas, and examples are imported from the contract.
3. Open an endpoint
Select an imported endpoint such as:
GET /users/{id}
Because the endpoint already has response schemas, the mock server has enough information to generate schema-shaped responses.
4. Copy the mock URL
Apidog provides mock endpoints automatically. Use the generated mock URL as the base URL for your client, frontend app, test suite, or Bruno collection.
Example shape:
https://mock.example.com/users/123
5. Send a request
Call the mock endpoint with your HTTP client.
Example:
curl https://mock.example.com/users/123
You get a JSON response based on the OpenAPI schema.
Example response:
{
"id": "usr_123",
"name": "Jane Doe",
"email": "jane@example.com",
"created_at": "2026-06-01T12:00:00Z"
}
6. Add edge cases when needed
For error-path testing, configure specific responses such as:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
Content-Type: application/json
{
"error": "Too many requests"
}
This lets you test client behavior for retries, fallback UI, and error handling without forcing the real backend into that state.
When Bruno plus an external mock is enough
You do not always need a spec-driven mock platform.
A lightweight external mock can be enough when:
- You only need one or two local endpoints
- Your mock responses are temporary
- Static JSON is acceptable
- You already use Mockoon, WireMock, Prism, or json-server
- Your team does not need shared mock URLs
- API changes are infrequent
In that case, Bruno can remain your request client while the mock server runs separately.
When a spec-driven mock is better
Use a spec-driven mock when:
- Multiple teams depend on the same API contract
- Frontend and backend work happen in parallel
- You need mocks for many endpoints
- You test multiple response codes and edge cases
- Your OpenAPI spec changes often
- You want docs, tests, and mocks to stay aligned
The trade-off is simple: external mocks preserve Bruno’s lightweight workflow, while spec-driven mocks reduce drift as the API grows.
FAQ
Does Bruno have a built-in mock server?
No. Bruno is an API client for sending requests and running tests. It does not include a native mock server. To mock endpoints, use an external tool or write your own stub server.
What is the easiest way to add mocking to a Bruno-style workflow?
Generate the mock from your OpenAPI spec. A tool like Apidog can read the spec and produce a mock URL, so design, mocking, testing, and documentation all use the same API contract.
Can I keep using Bruno and add a mock server alongside it?
Yes. Run an external mock tool such as Mockoon, WireMock, or Prism, then point Bruno at that mock server URL. This works, but your spec, requests, and mock data live separately and can drift.
Should I write my own mock server?
Only for small or temporary cases. A custom Express, Flask, or FastAPI stub is quick to start, but it becomes repetitive as endpoints, schemas, and edge cases increase.
If maintaining a separate mock layer is starting to cost more than it saves, try a spec-driven mock. Import your OpenAPI file into Apidog and generate a working mock URL without hosting another server.

Top comments (0)