Variable syntax
Reqbook supports two placeholder forms that can appear anywhere in request blocks, response blocks, and pipeline definitions.
Inline variable resolved from any variable source:
GET {{baseUrl}}/users/{{userId}}
Authorization: Bearer {{authToken}}
Path parameter shorthand for URL path segments, resolved from the same sources:
GET {{baseUrl}}/users/:id
Both forms are interchangeable from a resolution standpoint. Use :param in the path frontmatter field and URL paths; use {{name}} everywhere else.
Resolution priority
When the same variable name appears in more than one source, the highest-priority source wins. Reqbook resolves variables in this order, from highest to lowest:
| Priority | Source | Example |
|---|
| 1 (highest) | Pipeline step capture | Capture: response.body.id as userId |
| 2 | CLI --var flag | --var userId=42 |
| 3 | Endpoint frontmatter | userId: 42 in the YAML block |
| 4 | _shared/env.md for the selected env | ## dev section |
| 5 | .env.local | authToken=local-token |
| 6 (lowest) | RQB_* OS environment variables | RQB_AUTH_TOKEN=... |
The web UI, CLI, flows, and agent tools use the same priority order. A request that runs in the browser should resolve the same variables when an agent or CI runs it.
Priority in practice
RQB_USER_ID=from-os rqb exec api-docs/apis/users/get-user.md --var userId=from-cli
# {{userId}} resolves to "from-cli" CLI outranks OS env
Environment template and local values
api-docs/_shared/env.template.md stores the shared shape and safe defaults for each environment. api-docs/_shared/env.md stores the local values used at runtime and is gitignored by default. Select an environment with --env=<name>.
# Environments
## dev
```yaml
baseUrl: http://localhost:8080
pageSize: 20
```
## staging
```yaml
baseUrl: https://staging.example.com
pageSize: 20
```
## prod
```yaml
baseUrl: https://api.example.com
pageSize: 50
```
Do not put tokens, passwords, or API keys in either env markdown file. The Reqbook parser detects common secret patterns and exits with code 5 before any network request is made.
.env.local local secrets
.env.local uses standard dotenv syntax. It is gitignored by default and is never committed to version control.
authToken=local-development-token
webhookSecret=local-development-secret
stripeKey=sk_test_...
rqb init creates both api-docs/_shared/env.template.md and api-docs/_shared/env.md. It adds .env.local and api-docs/_shared/env.md to .gitignore automatically. Run rqb doctor to confirm both ignored entries are listed.
RQB_* environment variables
Reqbook reads only variables prefixed with RQB_ from the OS environment. The prefix is stripped and the remainder is converted to lower camelCase before resolution.
| OS variable | Reqbook variable |
|---|
RQB_AUTH_TOKEN | authToken |
RQB_BASE_URL | baseUrl |
RQB_USER_ID | userId |
CI/CD pattern
Set secrets as masked CI environment variables and map them with the RQB_ prefix:
env:
RQB_AUTH_TOKEN: ${{ secrets.API_TOKEN }}
RQB_BASE_URL: https://staging.example.com
This keeps secrets out of spec files entirely and works with any CI provider that supports environment variable injection.
Missing variables
If a variable cannot be resolved from any source, Reqbook exits with code 2 before making any network request. The error message names the variable and lists the ways to fix it.
api-docs/apis/users/get-user.md: unresolved variable "authToken"
Fix: define authToken in .env.local, pass --var authToken=..., or set RQB_AUTH_TOKEN.
Use --dry-run to check which variables are resolved and see the fully-rendered request without sending anything to the network. This is the fastest way to catch missing variables before running in CI.
Nested variables
the current Reqbook release does not resolve variables recursively. If resolving {{baseUrl}} produces a string that contains another {{variable}}, Reqbook returns an error rather than performing a second resolution pass.
# Invalid nested variable reference
apiHost: "{{host}}"
baseUrl: "https://{{apiHost}}"
This restriction is intentional. Recursive resolution can cause secret values to be embedded inside other values in ways that bypass output masking. Define each variable as a concrete value in the appropriate source instead.