Full reference

Complete schema documentation for every bolla concept.

Request definition

A request definition is any file ending in .bolla.yaml. bolla recursively scans your collection directory for them.

id: string          # unique within collection (required)
name: string        # display name
method: GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS
url: string         # supports {{variables}}

headers:
  X-My-Header: value

query:
  param_name: value

auth:               # see Authentication section

body:               # see Body section

assertions:         # see Assertions section

examples:           # used by mock server
  - name: success
    status: 200
    headers:
      Content-Type: application/json
    body: '{"id": "123"}'

Body

body:
  type: json          # json | raw | form
  content:            # for type: json — a YAML map serialized to JSON
    key: value
  # or for type: raw:
  raw: '{"manual":"json"}'
  content_type: application/json   # overrides default Content-Type

Authentication

TypeFieldsNotes
bearertokenSends Authorization: Bearer <token>
basicusername, passwordBase64-encodes and sends header
api_keyheader, valueCustom header name
oauth2flow_idReferences an OAuth2 flow — see OAuth2 section
noneExplicit no-auth (overrides collection default)
# Bearer example
auth:
  type: bearer
  token: "{{TOKEN}}"

# API key example
auth:
  type: api_key
  header: X-API-Key
  value: "{{API_KEY}}"

Assertions

Assertions run after every request. A failed assertion marks the run as failed in CI mode.

checkFieldsDescription
status_codevalue: intExact HTTP status match
status_invalues: [int]Status is one of the list
body_containstext: stringResponse body contains substring
body_json_pathpath: string, value: anyJSONPath expression equals value
header_equalsname: string, value: stringResponse header equals value
header_containsname: string, value: stringResponse header contains substring
elapsed_msmax: intResponse time < max milliseconds
response_sizemax: intBody size < max bytes

Variables

Use {"{{name}}"} anywhere in url, headers, body, auth. Variables are resolved from the active environment at request time.

# staging.env.yaml
id: staging
name: Staging
vars:
  base_url: https://api-staging.example.com
  TOKEN: ""           # overridden by env var BOLLA_VAR_TOKEN at runtime

Any vars field can be overridden by an environment variable named BOLLA_VAR_<UPPERCASE_KEY>. This is the recommended pattern for secrets in CI.

Protocols

ProtocolHow to use
HTTP/1.1 & HTTP/2Default. Any http:// or https:// URL.
GraphQLSet method: POST, body.type: json, include query and optional variables fields in body content.
WebSocketUse ws:// or wss:// URL. Add ws_messages: list to send after connect.
SSEUse HTTP GET to an SSE endpoint. bolla streams events and captures them in the response body.

Load & scenarios Core

A scenario file (*.scenario.yaml) defines a multi-step load test.

id: smoke
name: Smoke test

load:
  type: ramp            # ramp | constant | spike
  start_concurrency: 5
  end_concurrency: 50
  duration_s: 60

steps:
  - request_id: create-user
    extract:
      USER_ID: "$.id"         # JSONPath extraction into a variable
  - request_id: get-user
    vars:
      id: "{{USER_ID}}"
    think_time_ms: 500        # pause between steps (simulates real user)

gates:
  p50_ms:    { max: 100 }
  p95_ms:    { max: 300 }
  p99_ms:    { max: 800 }
  error_pct: { max: 0.5 }
  rps:       { min: 100 }
Load typeDescription
rampLinear ramp from start_concurrency to end_concurrency over duration_s
constantFixed concurrency for duration_s. Uses end_concurrency.
spikeRamp up, hold at peak, ramp down. Configure with ramp_s, hold_s.

Mock server Optional

bolla --mock --collection ./my-api --mock-port 3078

Serves your collection as an HTTP mock. Route matching uses method + url path from each request definition.

Example selection: by default the first example matching the request is returned. Override per-request with the header X-Bolla-Example: <name>.

Auto-generated responses: if no example matches, bolla generates realistic fake data based on field names. Fields named id, uuid, email, phone, name, price, created_at etc. receive appropriate fake values.

CI / CD gates Optional

bolla --ci --scenario smoke --env staging

Runs headless, prints a structured pass/fail summary, and exits 0 on pass or 1 on any gate failure.

Output files in .bolla/runs/<run-id>/:

Publish JUnit in GitHub Actions: add uses: EnricoMi/publish-unit-test-result-action@v2 pointing at .bolla/runs/**/junit.xml to get inline PR annotations.

OAuth2 Optional

Define flows in .bolla/oauth2.yaml:

flows:
  - id: my-service
    grant_type: client_credentials     # or authorization_code, device_code
    token_url: https://auth.example.com/token
    client_id: "{{OAUTH_CLIENT_ID}}"
    client_secret: "{{OAUTH_CLIENT_SECRET}}"
    scopes: [read, write]

Reference a flow from any request: auth: { type: oauth2, flow_id: my-service }.

Tokens are cached in .bolla/tokens/ encrypted with AES-256-GCM. Expired tokens are refreshed automatically.

Presets available for: Google, GitHub, Microsoft (Azure AD), Okta, Auth0.

OpenAPI contracts Optional

# Import a spec and generate a collection
bolla --import-spec ./openapi.yaml --output ./my-api/

# Detect drift between spec and live responses
bolla --drift --spec ./openapi.yaml --env staging

Supported formats: OpenAPI 3.0, OpenAPI 3.1, Swagger 2.0. Import creates one .bolla.yaml per operation with auto-generated assertions for required fields and response schema.

History & reports Optional

All runs are stored in .bolla/history.db (SQLite). Browse and filter via the UI or REST API.

Export formatEndpoint
CSVGET /api/runs/export?format=csv
HTML reportGET /api/runs/export?format=html
JSONGET /api/runs/export?format=json

Run-to-run comparison: GET /api/load-runs/compare?a=<id>&b=<id> returns delta percentages for all metrics, with improved: true/false per metric.

Polish bundle Optional

A collection of productivity extras:

AI assist Optional

Powered by Claude. You supply your own Anthropic API key — it never touches disk and is never sent anywhere except api.anthropic.com.

# Set key via env var (recommended for CI)
export ANTHROPIC_API_KEY=sk-ant-...

# Or set it in the UI: Settings → AI assist → API key
FeatureEndpointDescription
Assertion suggestionsPOST /api/ai/suggest-assertionsAnalyzes a response and suggests assertion rules
CI summaryPOST /api/ai/summarize-ciPlain-English summary of a CI run result
Load summaryPOST /api/ai/summarize-loadPlain-English analysis of a load test result
Set keyPOST /api/ai/keySet API key at runtime (in-memory only)

REST API

When running bolla --server, all capabilities are accessible via a local REST API on port 3077.

Core

MethodPathDescription
GET/api/requestsList all request definitions
GET/api/requests/:idGet a single request definition
POST/api/runExecute a request
GET/api/environmentsList environments
GET/api/runsSearch run history
GET/api/runs/exportExport history (format=csv|html|json)
GET/api/load-runsSearch load run history
GET/api/load-runs/compareCompare two load runs

Load

MethodPathDescription
POST/api/load/runStart a load test scenario
GET/api/load/statusPoll live metrics during a run
POST/api/load/stopAbort the current load test

CLI flags

FlagDefaultDescription
--serverfalseStart the API server + UI
--port3077Server port
--collection.Directory to scan for .bolla.yaml files
--envEnvironment ID to activate
--cifalseHeadless CI mode
--scenarioScenario ID or path for CI/load run
--loadfalseRun a load test (interactive)
--mockfalseStart the mock server
--mock-port3078Mock server port
--import-specPath to OpenAPI spec to import
--output.Output directory for imported collection
--versionPrint version and exit