# Configuration reference

> Every key in config/requizon.php, its environment variable and its default.

Source: https://boring-observability.dev/requizon/docs/configuration
Section: Configuration — Requizon documentation (version 0.3)
Updated: 2026-09-20

---

Requizon works with no configuration file at all. When you want to change something, publish it:

```bash
php artisan vendor:publish --tag=requizon-config
```

The published `config/requizon.php` explains every key in its comments. This page is the same information as a table, with a link to the page that covers each group in depth.

> **Nested arrays replace, they do not merge**
>
> Laravel merges the package defaults into your file one top-level key at a time. If your file has a `recording` array, it replaces the whole default `recording` array, so a key you leave out of it is missing rather than defaulted. Keep each nested array complete, and re-check it after upgrading Requizon.

## Switches

| Key | Env | Default | Purpose |
| --- | --- | --- | --- |
| `enabled` | `REQUIZON_ENABLED` | `true` | The master switch. `false` registers no recording middleware, no dashboard routes and no scheduled commands. Migrations still load. |
| `instrument.laravel_client` | `REQUIZON_INSTRUMENT_LARAVEL` | `true` | Installs the recording middleware on Laravel's HTTP client. `false` leaves the client alone and records only the [Guzzle stacks you instrument](https://boring-observability.dev/requizon/docs/what-gets-recorded#guzzle). |
| `instrument.promise_fallback` | `REQUIZON_PROMISE_FALLBACK` | `true` | Records a transfer whose handler never reported transfer stats, timing it by wall clock. See [the promise fallback](https://boring-observability.dev/requizon/docs/what-gets-recorded#fallback). |

## What is recorded, and under which name

| Key | Default | Purpose |
| --- | --- | --- |
| `ignore_hosts` | `[]` | `Str::is()` host patterns that are never recorded. [Ignoring hosts](https://boring-observability.dev/requizon/docs/what-gets-recorded#ignoring-hosts) |
| `apis` | `[]` | API name to `Str::is()` host patterns, and the redaction keys that API alone gets. A host no pattern matches is named after itself. [Naming APIs](https://boring-observability.dev/requizon/docs/naming-apis) |
| `paths.max_segments` | `4` | Path segments kept before the rest is replaced with `/*`. |
| `paths.max_segment_length` | `40` | A longer segment is treated as an identifier and stored as `:id`. |
| `paths.max_length` | `255` | The stored path is cut to this many bytes. It must fit the `VARCHAR(255)` column. |
| `paths.patterns` | `[]` | An allow-list of normalised paths. When set, anything unmatched is stored under `other_label`. [Paths and table size](https://boring-observability.dev/requizon/docs/paths) |
| `paths.other_label` | `'other'` | The path recorded for calls that match none of `paths.patterns`. |

An `apis` entry is either its host patterns, or an array that names them under `hosts` alongside the redaction keys that apply to that API alone. Both shapes can sit in the same list, and an entry that leaves its patterns bare can still carry the keys:

```php
'apis' => [
    'nausys' => ['ws.nausys.com', '*.nausys.com', 'redact' => ['l']],
    'stripe' => [
        'hosts' => ['api.stripe.com', 'files.stripe.com'],
        'redact' => ['card_number', 'cvc'],
    ],
    'sedna' => [
        'hosts' => ['sedna.example.com'],
        'redact_exact' => ['l', 'p'],
    ],
],
```

`redact` matches a parameter name by substring and `redact_exact` by the whole name, the same split as the two global lists below, and both are added to them for that API rather than replacing them. Rules are keyed by the resolved API name, so an entry with keys and no `hosts` carries them for a name that `resolveApiUsing()` mints. What they cover is on [Redaction and stored data](https://boring-observability.dev/requizon/docs/redaction).

## Recording and redaction

| Key | Default | Purpose |
| --- | --- | --- |
| `recording.response_body_max_bytes` | `65536` | How much of a failed call's response body is stored, and how much of a successful one the failure detector reads. |
| `recording.request_body_max_bytes` | `4096` | How much of an unparsed request body is stored when `store_unparsed_bodies` is on. |
| `recording.query_max_bytes` | `4096` | The cap on a stored query string's JSON. Parameters that do not fit are dropped whole and counted under `_truncated`, so a thousand `ids[]` cost one row and not the table. |
| `recording.max_body_read_bytes` | `262144` | A request body larger than this is never read, only measured. Keeps file uploads out of memory. |
| `recording.store_unparsed_bodies` | `false` | Store XML, SOAP and other bodies that cannot be parsed into named parameters verbatim, instead of by shape. |
| `recording.redact_patterns` | `pass`, `secret`, `token`, `apikey`, `api_key`, `auth` | A parameter whose lowercased name contains one of these is stored as `***`. It covers the query, the request body, the parsed body of a failed response and header names, on every API. |
| `recording.redact_exact` | `p`, `l`, `pwd` | A parameter with exactly this name is stored as `***`. One API's own keys go on its `apis` entry instead. [Redaction and stored data](https://boring-observability.dev/requizon/docs/redaction) |

## Header capture

`recording.headers` decides which headers are stored, with a mode per direction. Requests and responses each take `none`, `failures` (only calls recorded as a failure) or `all`.

| Key | Env | Default | Purpose |
| --- | --- | --- | --- |
| `recording.headers.request` | `REQUIZON_REQUEST_HEADERS` | `'none'` | Request headers are not stored until you ask for them. |
| `recording.headers.response` | `REQUIZON_RESPONSE_HEADERS` | `'failures'` | Response headers of failed calls are stored, the same calls whose response body is stored. |
| `recording.headers.only` | — | `[]` | When set, only headers matching these `Str::is()` patterns are stored, such as `x-ratelimit-*` or `retry-after`. |
| `recording.headers.except` | — | `[]` | Patterns removed from whatever `only` left. |
| `recording.headers.redact` | — | `authorization`, `proxy-authorization`, `cookie`, `set-cookie`, `*api-key*`, `*subscription-key*`, `x-functions-key` | Header names kept with every value replaced by `***`, matched case-insensitively as `Str::is()` patterns. Your list replaces this one, though a published config with no `headers.redact` key at all still gets it. [Headers](https://boring-observability.dev/requizon/docs/headers) |
| `recording.headers.max_bytes` | — | `16384` | The cap on each message's stored header JSON. A header that does not fit is dropped whole and counted under `_truncated`. |

The names in `redact_patterns` and `redact_exact`, and the ones an API's `apis` entry adds, mask a header as well as a parameter, so a provider's `X-Partner-Key` named there is masked without being named twice.

## Dashboard

| Key | Env | Default | Purpose |
| --- | --- | --- | --- |
| `path` | `REQUIZON_PATH` | `'requizon'` | The URI the dashboard is served from. |
| `domain` | `REQUIZON_DOMAIN` | `null` | Serve the dashboard from a dedicated host. `null` serves it on every host the application answers. |
| `middleware` | — | `['web']` | Applied to every dashboard route, before Requizon's own check of the `viewRequizon` gate. |
| `dashboard.windows` | — | `[24, 72, 168, 336]` | The time windows, in hours, offered by the window selector. |
| `dashboard.default_window` | — | `72` | The window shown first. A value not in `windows` falls back to the first entry. |
| `dashboard.per_page` | — | `50` | Rows per page on the requests list. [The dashboard](https://boring-observability.dev/requizon/docs/dashboard) |

## Storage, retention and scheduling

| Key | Env | Default | Purpose |
| --- | --- | --- | --- |
| `connection` | `REQUIZON_DB_CONNECTION` | `null` | The database connection Requizon's tables live on. `null` is the default connection. The aggregate needs it to be MySQL 8.0.20+. |
| `retention.detail_days` | — | `14` | Days `requizon_http_requests` rows are kept. |
| `retention.aggregate_days` | — | `365` | Days hourly rollup rows are kept. |
| `schedule.enabled` | `REQUIZON_SCHEDULE` | `true` | Register the aggregate and prune commands on Laravel's scheduler. `false` leaves scheduling to you. |
| `schedule.aggregate_hours` | — | `2` | How many past hours each scheduled aggregate run rebuilds. |
| `schedule.prune_at` | — | `'03:00'` | The daily time `requizon:prune` runs, in the scheduler's timezone. [Retention and scheduling](https://boring-observability.dev/requizon/docs/retention) |

## Callbacks

Five behaviours need code rather than a value, and are registered on `BoringO11y\Requizon\Requizon`, usually in the `boot()` method of your published `RequizonServiceProvider`:

| Method | Replaces | Covered in |
| --- | --- | --- |
| `resolveApiUsing()` | The `apis` host map. Returning `null` falls back to it. | [Naming APIs](https://boring-observability.dev/requizon/docs/naming-apis#resolver) |
| `resolvePathUsing()` | The built-in path normaliser. Returning `null` falls back to it. | [Paths and table size](https://boring-observability.dev/requizon/docs/paths#resolver) |
| `redactUsing()` | Nothing. It receives what the name rules already redacted, for request parameters and for the parsed body of a failed response. | [Redaction and stored data](https://boring-observability.dev/requizon/docs/redaction) |
| `detectFailuresUsing()` | Nothing. Without it no successful response body is read. | [Failure detection](https://boring-observability.dev/requizon/docs/failure-detection) |
| `auth()` | The `viewRequizon` gate check. The base provider registers one for you. | [The dashboard](https://boring-observability.dev/requizon/docs/dashboard#access) |

## After changing configuration

If you cache configuration in production, run `php artisan config:cache` again after editing the file, and restart long-running processes (queue workers, Octane) so they pick up the new values. `php artisan about` shows whether the HTTP client is instrumented and the path the dashboard is served from, which is a quick way to confirm what the running configuration actually is.


## Common questions

### How do I turn Requizon off in my test suite?

Set REQUIZON_ENABLED=false in phpunit.xml. With the master switch off Requizon registers no recording middleware, no dashboard routes and no scheduled commands. Left on, every Http::fake() response your tests produce is written to requizon_http_requests.
