# Configuration reference

Every configuration key of BrowserHive (50 keys), generated from the zod schema in `@browserhive/contracts/config`. For a guided introduction see [the configuration guide](/docs/guide/configuration/).

## Precedence

Four sources, lowest to highest precedence. **Rightmost wins.**

```
defaults  <  environment (BROWSERHIVE_*)  <  browserhive.config.json  <  CLI flags
```

Standard `OTEL_*` variables are read as a sub-source just below `BROWSERHIVE_*` (provenance `env(otel)`). When a key is supplied by more than one source, startup logs one line per key naming the winner and what it shadowed; secret values render as `<redacted>`:

```
config: maxSessions=8 (cli) shadows config-file=4, env=2
config: logLevel=debug (config-file) shadows env=info
config: authTokens=<redacted> (cli) shadows env=<redacted>
```

The same provenance is shown by `browserhive config show`, the System page of the dashboard and `GET /api/v1/system/config`. An empty value in the environment or the config file is a usage error, not "unset".

## Naming

Every key has one camelCase name. The other spellings are mechanical: `--maxSessions`, `BROWSERHIVE_MAX_SESSIONS`, `"maxSessions"`. CLI flags are case-sensitive; kebab-case flags are unknown and fail with a "did you mean" hint. Unknown flags, environment variables and file keys stop startup with exit code 64.

| Canonical key | CLI flag | Environment variable | Config file key |
|---|---|---|---|
| `maxSessions` | `--maxSessions` | `BROWSERHIVE_MAX_SESSIONS` | `"maxSessions"` |
| `otelEndpoint` | `--otelEndpoint` | `BROWSERHIVE_OTEL_ENDPOINT` | `"otelEndpoint"` |
| `allowInsecureBind` | `--allowInsecureBind` | `BROWSERHIVE_ALLOW_INSECURE_BIND` | `"allowInsecureBind"` |

## Config file discovery

First hit wins: `--config <path>` (or `BROWSERHIVE_CONFIG`), then `./browserhive.config.json`, then `<dataDir>/browserhive.config.json`. The file is plain JSON; `"$schema"` is the only extra key tolerated. A config file found inside the data directory may not set `dataDir`. The JSON Schema is [config.schema.json](/docs/reference/config.schema.json) (also printed by `browserhive config schema`).

## Value grammars

| Grammar | Accepted forms |
|---|---|
| boolean | `true`, `false`, `1`, `0`, `yes`, `no` (case-insensitive). CLI: `--admin` means true, `--admin=false` or `--noAdmin` sets false; `--admin false` is not accepted. |
| duration | integer plus `ms`, `s`, `m`, `h` or `d`; a bare integer is milliseconds. |
| bytes | integer plus `B`, `KiB`, `MiB`, `GiB`, `KB`, `MB` or `GB`; a bare integer is bytes. |
| integer / port | decimal integer, range-checked per key; ports are 1–65535. |
| host | IPv4 literal, IPv6 literal (with or without brackets) or an RFC 1123 hostname. |
| enum | exact member, case-sensitive. |
| path | relative paths resolve against the working directory (CLI, env) or the config file directory (file). |
| list | CLI/env: comma-separated, trimmed, no empty items. File: JSON array of strings. |
| map | CLI/env: `k=v,k2=v2` (first `=` splits). File: JSON object of strings. |
| url | absolute `http:` or `https:` URL. |

## OpenTelemetry environment variables

| Variable | Key |
|---|---|
| `OTEL_EXPORTER_OTLP_ENDPOINT` | [`otelEndpoint`](#otelEndpoint) |
| `OTEL_EXPORTER_OTLP_HEADERS` | [`otelHeaders`](#otelHeaders) |
| `OTEL_EXPORTER_OTLP_PROTOCOL` | [`otelProtocol`](#otelProtocol) |
| `OTEL_SERVICE_NAME` | [`otelServiceName`](#otelServiceName) |
| `OTEL_TRACES_SAMPLER_ARG` | [`otelSampleRatio`](#otelSampleRatio) |

## Cross-field rules

Checked after all sources are merged. Violations exit with code 64 unless noted.

1. `minAttentionWait` must be less than `attentionTimeout` when it is greater than 0.
2. `humanize=true` requires `stealth` to be `standard` or `max`.
3. `fingerprint=true` (set explicitly) requires `stealth` to be `standard` or `max`.
4. `captcha=attention` (set explicitly) requires `admin=true` and `transport=http`.
5. `admin=true` requires `transport=http` (`ADMIN_REQUIRES_HTTP`, exit 3).
6. `auth=token` requires `transport=http`.
7. `otelEndpoint`, `otelProtocol`, `otelHeaders`, `otelServiceName` and `otelSampleRatio` require `otel=true`.
8. `trustedProxies` requires a non-loopback `host`.
9. `screenshotTrace=true` requires `trace=true`.
10. `blocklistWatch=true` requires `blocklist` to be set.
11. A non-loopback `host` without `auth=token` and without `allowInsecureBind=true` is refused (`INSECURE_BIND_REFUSED`, exit 3).

## Reserved keys

These names are reserved for future releases. Setting any of them fails fast with a "reserved" message: `proxy`, `proxies`, `proxyRotation`, `notifications`, `notificationChannels`, `otelMetricsInterval`, `captchaSolver`, `extensions`, `profiles`, `resourceBudget`, `tenant`.

## Server

| Key | CLI | Environment | Default |
|---|---|---|---|
| [`config`](#config) | `--config` | `BROWSERHIVE_CONFIG` | unset |
| [`transport`](#transport) | `--transport` | `BROWSERHIVE_TRANSPORT` | `http` |
| [`host`](#host) | `--host` | `BROWSERHIVE_HOST` | `127.0.0.1` |
| [`port`](#port) | `--port` | `BROWSERHIVE_PORT` | `9876` |
| [`auth`](#auth) | `--auth` | `BROWSERHIVE_AUTH` | `off` |
| [`authTokens`](#authTokens) | `--authTokens` | `BROWSERHIVE_AUTH_TOKENS` | empty list |
| [`allowInsecureBind`](#allowInsecureBind) | `--allowInsecureBind` | `BROWSERHIVE_ALLOW_INSECURE_BIND` | `false` |
| [`trustedProxies`](#trustedProxies) | `--trustedProxies` | `BROWSERHIVE_TRUSTED_PROXIES` | empty list |
| [`admin`](#admin) | `--admin` | `BROWSERHIVE_ADMIN` | `false` |
| [`dataDir`](#dataDir) | `--dataDir` | `BROWSERHIVE_DATA_DIR` | derived (platform) |
| [`shutdownTimeout`](#shutdownTimeout) | `--shutdownTimeout` | `BROWSERHIVE_SHUTDOWN_TIMEOUT` | `20s` |
| [`sessionCloseTimeout`](#sessionCloseTimeout) | `--sessionCloseTimeout` | `BROWSERHIVE_SESSION_CLOSE_TIMEOUT` | `10s` |

<a id="config"></a>
### `config`

Config file path. CLI and environment only: a config file cannot point at another.

| Property | Value |
|---|---|
| CLI flag | `--config` |
| Environment | `BROWSERHIVE_CONFIG` |
| Config file | not accepted |
| Type | a non-empty file system path |
| Default | unset |
| Notes | restart required · CLI and environment only (not accepted in the config file) |

<a id="transport"></a>
### `transport`

Transport to serve. stdio is the single-client fallback without dashboard or attention.

| Property | Value |
|---|---|
| CLI flag | `--transport` |
| Environment | `BROWSERHIVE_TRANSPORT` |
| Config file | `"transport"` |
| Type | one of: http, stdio |
| Default | `http` |
| Notes | restart required · reserved values `ws` fail fast |

<a id="host"></a>
### `host`

Bind address. A non-loopback host requires auth=token or allowInsecureBind=true.

| Property | Value |
|---|---|
| CLI flag | `--host` |
| Environment | `BROWSERHIVE_HOST` |
| Config file | `"host"` |
| Type | an IPv4 address, an IPv6 address, or a hostname |
| Default | `127.0.0.1` |
| Notes | restart required |

<a id="port"></a>
### `port`

Bind port for MCP, REST, WebSocket and the dashboard.

| Property | Value |
|---|---|
| CLI flag | `--port` |
| Environment | `BROWSERHIVE_PORT` |
| Config file | `"port"` |
| Type | a port between 1 and 65535 |
| Default | `9876` |
| Notes | restart required |

<a id="auth"></a>
### `auth`

MCP authentication. token requires a bearer on /mcp and enforces session ownership.

| Property | Value |
|---|---|
| CLI flag | `--auth` |
| Environment | `BROWSERHIVE_AUTH` |
| Config file | `"auth"` |
| Type | one of: off, token |
| Default | `off` |
| Notes | restart required |

<a id="authTokens"></a>
### `authTokens`

Agent bearer tokens as name:token pairs (env preferred). Merged with stored tokens, never persisted.

| Property | Value |
|---|---|
| CLI flag | `--authTokens` |
| Environment | `BROWSERHIVE_AUTH_TOKENS` |
| Config file | `"authTokens"` |
| Type | a comma-separated list of 'name:token' pairs (token >= 32 characters) |
| Default | empty list |
| Examples | `ci-runner:REPLACE_WITH_32_PLUS_CHARS` |
| Notes | restart required · secret (rendered `<redacted>`) |

<a id="allowInsecureBind"></a>
### `allowInsecureBind`

Acknowledge binding a non-loopback host without authentication.

| Property | Value |
|---|---|
| CLI flag | `--allowInsecureBind` |
| Environment | `BROWSERHIVE_ALLOW_INSECURE_BIND` |
| Config file | `"allowInsecureBind"` |
| Type | a boolean: 'true', 'false', '1', '0', 'yes' or 'no' |
| Default | `false` |
| Notes | restart required |

<a id="trustedProxies"></a>
### `trustedProxies`

Peers whose X-Forwarded-For is honoured (IPs or CIDR ranges). Never used on a loopback bind.

| Property | Value |
|---|---|
| CLI flag | `--trustedProxies` |
| Environment | `BROWSERHIVE_TRUSTED_PROXIES` |
| Config file | `"trustedProxies"` |
| Type | a comma-separated list of IP addresses or CIDR ranges |
| Default | empty list |
| Notes | restart required |

<a id="admin"></a>
### `admin`

Enable the dashboard, REST API, WebSocket and trace viewer (http only).

| Property | Value |
|---|---|
| CLI flag | `--admin` |
| Environment | `BROWSERHIVE_ADMIN` |
| Config file | `"admin"` |
| Type | a boolean: 'true', 'false', '1', '0', 'yes' or 'no' |
| Default | `false` |
| Notes | restart required |

<a id="dataDir"></a>
### `dataDir`

Data directory (database, sessions, auth states, uploads, backups). Defaults to the OS data dir.

| Property | Value |
|---|---|
| CLI flag | `--dataDir` |
| Environment | `BROWSERHIVE_DATA_DIR` |
| Config file | `"dataDir"` |
| Type | a non-empty file system path |
| Default | derived from the OS: `~/Library/Application Support/BrowserHive` (macOS), `%LOCALAPPDATA%\BrowserHive` (Windows), `$XDG_DATA_HOME/browserhive` or `~/.local/share/browserhive` (Linux) |
| Notes | restart required |

<a id="shutdownTimeout"></a>
### `shutdownTimeout`

Total budget for a graceful stop (listeners, then sessions, then storage).

| Property | Value |
|---|---|
| CLI flag | `--shutdownTimeout` |
| Environment | `BROWSERHIVE_SHUTDOWN_TIMEOUT` |
| Config file | `"shutdownTimeout"` |
| Type | a duration like '2h', '30m', '90s', '500ms', or an integer of milliseconds |
| Default | `20s` |
| Notes | restart required |

<a id="sessionCloseTimeout"></a>
### `sessionCloseTimeout`

Per-session close and trace-finalize cap.

| Property | Value |
|---|---|
| CLI flag | `--sessionCloseTimeout` |
| Environment | `BROWSERHIVE_SESSION_CLOSE_TIMEOUT` |
| Config file | `"sessionCloseTimeout"` |
| Type | a duration like '2h', '30m', '90s', '500ms', or an integer of milliseconds |
| Default | `10s` |
| Notes | restart required |

## Sessions

| Key | CLI | Environment | Default |
|---|---|---|---|
| [`persistence`](#persistence) | `--persistence` | `BROWSERHIVE_PERSISTENCE` | `memory` |
| [`defaultHeadless`](#defaultHeadless) | `--defaultHeadless` | `BROWSERHIVE_DEFAULT_HEADLESS` | `true` |
| [`defaultChannel`](#defaultChannel) | `--defaultChannel` | `BROWSERHIVE_DEFAULT_CHANNEL` | `chromium` |
| [`maxSessions`](#maxSessions) | `--maxSessions` | `BROWSERHIVE_MAX_SESSIONS` | derived (hostMemory) |
| [`sessionLease`](#sessionLease) | `--sessionLease` | `BROWSERHIVE_SESSION_LEASE` | `2h` |
| [`attentionTimeout`](#attentionTimeout) | `--attentionTimeout` | `BROWSERHIVE_ATTENTION_TIMEOUT` | `6h` |
| [`minAttentionWait`](#minAttentionWait) | `--minAttentionWait` | `BROWSERHIVE_MIN_ATTENTION_WAIT` | `30m` |
| [`allowEvaluate`](#allowEvaluate) | `--allowEvaluate` | `BROWSERHIVE_ALLOW_EVALUATE` | `true` |
| [`blocklist`](#blocklist) | `--blocklist` | `BROWSERHIVE_BLOCKLIST` | unset |
| [`blocklistWatch`](#blocklistWatch) | `--blocklistWatch` | `BROWSERHIVE_BLOCKLIST_WATCH` | `false` |
| [`vault`](#vault) | `--vault` | `BROWSERHIVE_VAULT` | `off` |

<a id="persistence"></a>
### `persistence`

Default persistence mode; launch_session persistence_mode overrides per session.

| Property | Value |
|---|---|
| CLI flag | `--persistence` |
| Environment | `BROWSERHIVE_PERSISTENCE` |
| Config file | `"persistence"` |
| Type | one of: memory, persistent, storage-state |
| Default | `memory` |
| Notes | restart required · reserved values `blueprint` fail fast |

<a id="defaultHeadless"></a>
### `defaultHeadless`

Default headless mode; launch_session headless overrides per session.

| Property | Value |
|---|---|
| CLI flag | `--defaultHeadless` |
| Environment | `BROWSERHIVE_DEFAULT_HEADLESS` |
| Config file | `"defaultHeadless"` |
| Type | a boolean: 'true', 'false', '1', '0', 'yes' or 'no' |
| Default | `true` |
| Notes | restart required |

<a id="defaultChannel"></a>
### `defaultChannel`

Default browser channel; launch_session channel overrides per session.

| Property | Value |
|---|---|
| CLI flag | `--defaultChannel` |
| Environment | `BROWSERHIVE_DEFAULT_CHANNEL` |
| Config file | `"defaultChannel"` |
| Type | one of: chromium, chrome, edge |
| Default | `chromium` |
| Notes | restart required |

<a id="maxSessions"></a>
### `maxSessions`

Maximum concurrent browser sessions, or unbounded. Derived from host RAM when unset (min(floor(GiB / 1.5), 20)).

| Property | Value |
|---|---|
| CLI flag | `--maxSessions` |
| Environment | `BROWSERHIVE_MAX_SESSIONS` |
| Config file | `"maxSessions"` |
| Type | an integer >= 1 or 'unbounded' |
| Default | derived from host RAM: `min(floor(RAM_GiB / 1.5), 20)` |
| Notes | restart required |

<a id="sessionLease"></a>
### `sessionLease`

Sliding inactivity lease after which an idle session is reaped.

| Property | Value |
|---|---|
| CLI flag | `--sessionLease` |
| Environment | `BROWSERHIVE_SESSION_LEASE` |
| Config file | `"sessionLease"` |
| Type | a duration of at least '1m' |
| Default | `2h` |
| Notes | restart required |

<a id="attentionTimeout"></a>
### `attentionTimeout`

Server cap on how long request_attention may block.

| Property | Value |
|---|---|
| CLI flag | `--attentionTimeout` |
| Environment | `BROWSERHIVE_ATTENTION_TIMEOUT` |
| Config file | `"attentionTimeout"` |
| Type | a duration of at least '1m' |
| Default | `6h` |
| Notes | restart required |

<a id="minAttentionWait"></a>
### `minAttentionWait`

Floor for request_attention max_wait; 0 disables it. Must be less than attentionTimeout.

| Property | Value |
|---|---|
| CLI flag | `--minAttentionWait` |
| Environment | `BROWSERHIVE_MIN_ATTENTION_WAIT` |
| Config file | `"minAttentionWait"` |
| Type | a duration like '2h', '30m', '90s', '500ms', or an integer of milliseconds |
| Default | `30m` |
| Notes | restart required |

<a id="allowEvaluate"></a>
### `allowEvaluate`

Allow the evaluate tool. false makes every evaluate return EVALUATE_DISABLED.

| Property | Value |
|---|---|
| CLI flag | `--allowEvaluate` |
| Environment | `BROWSERHIVE_ALLOW_EVALUATE` |
| Config file | `"allowEvaluate"` |
| Type | a boolean: 'true', 'false', '1', '0', 'yes' or 'no' |
| Default | `true` |
| Notes | restart required |

<a id="blocklist"></a>
### `blocklist`

URL blocklist file (one glob per line). Unreadable at startup is fatal.

| Property | Value |
|---|---|
| CLI flag | `--blocklist` |
| Environment | `BROWSERHIVE_BLOCKLIST` |
| Config file | `"blocklist"` |
| Type | a non-empty file system path |
| Default | unset |
| Notes | restart required |

<a id="blocklistWatch"></a>
### `blocklistWatch`

Reload the blocklist when the file changes (debounced). Requires blocklist.

| Property | Value |
|---|---|
| CLI flag | `--blocklistWatch` |
| Environment | `BROWSERHIVE_BLOCKLIST_WATCH` |
| Config file | `"blocklistWatch"` |
| Type | a boolean: 'true', 'false', '1', '0', 'yes' or 'no' |
| Default | `false` |
| Notes | restart required |

<a id="vault"></a>
### `vault`

Credential vault backend.

| Property | Value |
|---|---|
| CLI flag | `--vault` |
| Environment | `BROWSERHIVE_VAULT` |
| Config file | `"vault"` |
| Type | one of: off, bitwarden |
| Default | `off` |
| Notes | restart required · reserved values `local`, `onepassword`, `http` fail fast |

## Stealth

| Key | CLI | Environment | Default |
|---|---|---|---|
| [`stealth`](#stealth) | `--stealth` | `BROWSERHIVE_STEALTH` | `standard` |
| [`stealthDriver`](#stealthDriver) | `--stealthDriver` | `BROWSERHIVE_STEALTH_DRIVER` | `auto` |
| [`fingerprint`](#fingerprint) | `--fingerprint` | `BROWSERHIVE_FINGERPRINT` | derived (stealth) |
| [`humanize`](#humanize) | `--humanize` | `BROWSERHIVE_HUMANIZE` | `false` |
| [`captcha`](#captcha) | `--captcha` | `BROWSERHIVE_CAPTCHA` | `attention` |

<a id="stealth"></a>
### `stealth`

Stealth level. max also defaults fingerprint to true.

| Property | Value |
|---|---|
| CLI flag | `--stealth` |
| Environment | `BROWSERHIVE_STEALTH` |
| Config file | `"stealth"` |
| Type | one of: off, standard, max |
| Default | `standard` |
| Notes | restart required |

<a id="stealthDriver"></a>
### `stealthDriver`

Chromium driver for stealth sessions. auto uses Patchright when installed, else Playwright.

| Property | Value |
|---|---|
| CLI flag | `--stealthDriver` |
| Environment | `BROWSERHIVE_STEALTH_DRIVER` |
| Config file | `"stealthDriver"` |
| Type | one of: auto, patchright, playwright |
| Default | `auto` |
| Notes | restart required |

<a id="fingerprint"></a>
### `fingerprint`

Coherent fingerprint identity per session. Defaults to true only when stealth=max.

| Property | Value |
|---|---|
| CLI flag | `--fingerprint` |
| Environment | `BROWSERHIVE_FINGERPRINT` |
| Config file | `"fingerprint"` |
| Type | a boolean: 'true', 'false', '1', '0', 'yes' or 'no' |
| Default | derived from `stealth`: `true` when `stealth=max`, otherwise `false` |
| Notes | restart required |

<a id="humanize"></a>
### `humanize`

Human-like cursor movement and typing cadence. Requires stealth standard or max.

| Property | Value |
|---|---|
| CLI flag | `--humanize` |
| Environment | `BROWSERHIVE_HUMANIZE` |
| Config file | `"humanize"` |
| Type | a boolean: 'true', 'false', '1', '0', 'yes' or 'no' |
| Default | `false` |
| Notes | restart required |

<a id="captcha"></a>
### `captcha`

CAPTCHA policy. attention hands the page to an operator (needs admin and http).

| Property | Value |
|---|---|
| CLI flag | `--captcha` |
| Environment | `BROWSERHIVE_CAPTCHA` |
| Config file | `"captcha"` |
| Type | one of: attention, off |
| Default | `attention` |
| Notes | restart required · reserved values `solver` fail fast |

## Logging

| Key | CLI | Environment | Default |
|---|---|---|---|
| [`logLevel`](#logLevel) | `--logLevel` | `BROWSERHIVE_LOG_LEVEL` | `info` |
| [`logFormat`](#logFormat) | `--logFormat` | `BROWSERHIVE_LOG_FORMAT` | `auto` |
| [`color`](#color) | `--color` | `BROWSERHIVE_COLOR` | `auto` |
| [`logRingSize`](#logRingSize) | `--logRingSize` | `BROWSERHIVE_LOG_RING_SIZE` | `5000` |
| [`logPersist`](#logPersist) | `--logPersist` | `BROWSERHIVE_LOG_PERSIST` | `off` |

<a id="logLevel"></a>
### `logLevel`

Log level, optionally per module: info,sessions=debug,http=warn. Levels: error, warn, info, debug, trace.

| Property | Value |
|---|---|
| CLI flag | `--logLevel` |
| Environment | `BROWSERHIVE_LOG_LEVEL` |
| Config file | `"logLevel"` |
| Type | a level spec like 'info' or 'info,sessions=debug,http=warn' (levels: error, warn, info, debug, trace) |
| Default | `info` |
| Examples | `info`, `info,sessions=debug` |
| Notes | runtime-adjustable |

<a id="logFormat"></a>
### `logFormat`

Log renderer. auto is pretty on a TTY (http only), otherwise JSON lines.

| Property | Value |
|---|---|
| CLI flag | `--logFormat` |
| Environment | `BROWSERHIVE_LOG_FORMAT` |
| Config file | `"logFormat"` |
| Type | one of: auto, json, pretty |
| Default | `auto` |
| Notes | runtime-adjustable |

<a id="color"></a>
### `color`

Colour for logs and CLI output. auto honours NO_COLOR, FORCE_COLOR, TERM=dumb and TTY.

| Property | Value |
|---|---|
| CLI flag | `--color` |
| Environment | `BROWSERHIVE_COLOR` |
| Config file | `"color"` |
| Type | one of: auto, always, never |
| Default | `auto` |
| Notes | restart required |

<a id="logRingSize"></a>
### `logRingSize`

Records kept in the in-process log ring buffer served to the dashboard.

| Property | Value |
|---|---|
| CLI flag | `--logRingSize` |
| Environment | `BROWSERHIVE_LOG_RING_SIZE` |
| Config file | `"logRingSize"` |
| Type | an integer between 100 and 1000000 |
| Default | `5000` |
| Notes | restart required |

<a id="logPersist"></a>
### `logPersist`

Durable logs table threshold (retention 3 days). off disables the sink.

| Property | Value |
|---|---|
| CLI flag | `--logPersist` |
| Environment | `BROWSERHIVE_LOG_PERSIST` |
| Config file | `"logPersist"` |
| Type | one of: info, warn, off |
| Default | `off` |
| Notes | restart required |

## Recording and retention

| Key | CLI | Environment | Default |
|---|---|---|---|
| [`trace`](#trace) | `--trace` | `BROWSERHIVE_TRACE` | derived (admin) |
| [`screenshotTrace`](#screenshotTrace) | `--screenshotTrace` | `BROWSERHIVE_SCREENSHOT_TRACE` | `false` |
| [`screencastQuality`](#screencastQuality) | `--screencastQuality` | `BROWSERHIVE_SCREENCAST_QUALITY` | `60` |
| [`recordToolResults`](#recordToolResults) | `--recordToolResults` | `BROWSERHIVE_RECORD_TOOL_RESULTS` | `full` |
| [`retentionDays`](#retentionDays) | `--retentionDays` | `BROWSERHIVE_RETENTION_DAYS` | `7` |
| [`retentionBytes`](#retentionBytes) | `--retentionBytes` | `BROWSERHIVE_RETENTION_BYTES` | `1GiB` |
| [`backupsKeep`](#backupsKeep) | `--backupsKeep` | `BROWSERHIVE_BACKUPS_KEEP` | `5` |
| [`urlQueryAllowlist`](#urlQueryAllowlist) | `--urlQueryAllowlist` | `BROWSERHIVE_URL_QUERY_ALLOWLIST` | empty list |

<a id="trace"></a>
### `trace`

Record a Playwright trace per session. Defaults to the value of admin.

| Property | Value |
|---|---|
| CLI flag | `--trace` |
| Environment | `BROWSERHIVE_TRACE` |
| Config file | `"trace"` |
| Type | a boolean: 'true', 'false', '1', '0', 'yes' or 'no' |
| Default | derived from `admin`: same value |
| Notes | restart required |

<a id="screenshotTrace"></a>
### `screenshotTrace`

Store a JPEG after each tool call. Requires trace=true.

| Property | Value |
|---|---|
| CLI flag | `--screenshotTrace` |
| Environment | `BROWSERHIVE_SCREENSHOT_TRACE` |
| Config file | `"screenshotTrace"` |
| Type | a boolean: 'true', 'false', '1', '0', 'yes' or 'no' |
| Default | `false` |
| Notes | restart required |

<a id="screencastQuality"></a>
### `screencastQuality`

JPEG quality of the live view screencast (1-100).

| Property | Value |
|---|---|
| CLI flag | `--screencastQuality` |
| Environment | `BROWSERHIVE_SCREENCAST_QUALITY` |
| Config file | `"screencastQuality"` |
| Type | an integer between 1 and 100 |
| Default | `60` |
| Notes | restart required |

<a id="recordToolResults"></a>
### `recordToolResults`

What of a tool result is persisted: full text (capped), shape (keys and sizes) or none.

| Property | Value |
|---|---|
| CLI flag | `--recordToolResults` |
| Environment | `BROWSERHIVE_RECORD_TOOL_RESULTS` |
| Config file | `"recordToolResults"` |
| Type | one of: full, shape, none |
| Default | `full` |
| Notes | restart required |

<a id="retentionDays"></a>
### `retentionDays`

Days to keep events and artifacts. Must be at least 1; use a large number to keep longer.

| Property | Value |
|---|---|
| CLI flag | `--retentionDays` |
| Environment | `BROWSERHIVE_RETENTION_DAYS` |
| Config file | `"retentionDays"` |
| Type | an integer >= 1 |
| Default | `7` |
| Notes | restart required |

<a id="retentionBytes"></a>
### `retentionBytes`

Disk budget for the database and artifacts before the oldest rows are pruned.

| Property | Value |
|---|---|
| CLI flag | `--retentionBytes` |
| Environment | `BROWSERHIVE_RETENTION_BYTES` |
| Config file | `"retentionBytes"` |
| Type | a size of at least '64MiB' |
| Default | `1GiB` |
| Notes | restart required |

<a id="backupsKeep"></a>
### `backupsKeep`

Pre-migration database backups to retain.

| Property | Value |
|---|---|
| CLI flag | `--backupsKeep` |
| Environment | `BROWSERHIVE_BACKUPS_KEEP` |
| Config file | `"backupsKeep"` |
| Type | an integer >= 1 |
| Default | `5` |
| Notes | restart required |

<a id="urlQueryAllowlist"></a>
### `urlQueryAllowlist`

Query parameter names kept when URLs are sanitized for storage; all others are stripped.

| Property | Value |
|---|---|
| CLI flag | `--urlQueryAllowlist` |
| Environment | `BROWSERHIVE_URL_QUERY_ALLOWLIST` |
| Config file | `"urlQueryAllowlist"` |
| Type | a comma-separated list like 'a,b,c' (or a JSON array of strings) |
| Default | empty list |
| Notes | restart required |

## Telemetry

| Key | CLI | Environment | Default |
|---|---|---|---|
| [`otel`](#otel) | `--otel` | `BROWSERHIVE_OTEL` | `false` |
| [`otelEndpoint`](#otelEndpoint) | `--otelEndpoint` | `BROWSERHIVE_OTEL_ENDPOINT` | `http://127.0.0.1:4318` |
| [`otelProtocol`](#otelProtocol) | `--otelProtocol` | `BROWSERHIVE_OTEL_PROTOCOL` | `http/protobuf` |
| [`otelHeaders`](#otelHeaders) | `--otelHeaders` | `BROWSERHIVE_OTEL_HEADERS` | `{}` |
| [`otelServiceName`](#otelServiceName) | `--otelServiceName` | `BROWSERHIVE_OTEL_SERVICE_NAME` | `browserhive` |
| [`otelSampleRatio`](#otelSampleRatio) | `--otelSampleRatio` | `BROWSERHIVE_OTEL_SAMPLE_RATIO` | `1` |
| [`otelSignals`](#otelSignals) | `--otelSignals` | `BROWSERHIVE_OTEL_SIGNALS` | `["traces","metrics","logs"]` |
| [`otelVerbose`](#otelVerbose) | `--otelVerbose` | `BROWSERHIVE_OTEL_VERBOSE` | `false` |
| [`otelTraceUrlTemplate`](#otelTraceUrlTemplate) | `--otelTraceUrlTemplate` | `BROWSERHIVE_OTEL_TRACE_URL_TEMPLATE` | unset |

<a id="otel"></a>
### `otel`

Export traces, metrics and logs over OTLP/HTTP.

| Property | Value |
|---|---|
| CLI flag | `--otel` |
| Environment | `BROWSERHIVE_OTEL` |
| Config file | `"otel"` |
| Type | a boolean: 'true', 'false', '1', '0', 'yes' or 'no' |
| Default | `false` |
| Notes | restart required |

<a id="otelEndpoint"></a>
### `otelEndpoint`

OTLP/HTTP base URL; /v1/traces, /v1/metrics and /v1/logs are appended.

| Property | Value |
|---|---|
| CLI flag | `--otelEndpoint` |
| Environment | `BROWSERHIVE_OTEL_ENDPOINT` |
| Config file | `"otelEndpoint"` |
| Type | an absolute http: or https: URL like 'http://127.0.0.1:4318' |
| Default | `http://127.0.0.1:4318` |
| Notes | restart required |

<a id="otelProtocol"></a>
### `otelProtocol`

OTLP/HTTP encoding.

| Property | Value |
|---|---|
| CLI flag | `--otelProtocol` |
| Environment | `BROWSERHIVE_OTEL_PROTOCOL` |
| Config file | `"otelProtocol"` |
| Type | one of: http/protobuf, http/json |
| Default | `http/protobuf` |
| Notes | restart required |

<a id="otelHeaders"></a>
### `otelHeaders`

Headers sent with every OTLP request, e.g. Authorization=Bearer …

| Property | Value |
|---|---|
| CLI flag | `--otelHeaders` |
| Environment | `BROWSERHIVE_OTEL_HEADERS` |
| Config file | `"otelHeaders"` |
| Type | a comma-separated map like 'k=v,k2=v2' (or a JSON object of strings) |
| Default | `{}` |
| Notes | restart required · secret (rendered `<redacted>`) |

<a id="otelServiceName"></a>
### `otelServiceName`

service.name resource attribute.

| Property | Value |
|---|---|
| CLI flag | `--otelServiceName` |
| Environment | `BROWSERHIVE_OTEL_SERVICE_NAME` |
| Config file | `"otelServiceName"` |
| Type | a non-empty string |
| Default | `browserhive` |
| Notes | restart required |

<a id="otelSampleRatio"></a>
### `otelSampleRatio`

Parent-based ratio sampler for traces (0-1).

| Property | Value |
|---|---|
| CLI flag | `--otelSampleRatio` |
| Environment | `BROWSERHIVE_OTEL_SAMPLE_RATIO` |
| Config file | `"otelSampleRatio"` |
| Type | a number between 0 and 1 |
| Default | `1` |
| Notes | restart required |

<a id="otelSignals"></a>
### `otelSignals`

Signals to export.

| Property | Value |
|---|---|
| CLI flag | `--otelSignals` |
| Environment | `BROWSERHIVE_OTEL_SIGNALS` |
| Config file | `"otelSignals"` |
| Type | a comma-separated subset of: traces, metrics, logs |
| Default | `["traces","metrics","logs"]` |
| Notes | restart required |

<a id="otelVerbose"></a>
### `otelVerbose`

Also export db.query and cdp.command spans.

| Property | Value |
|---|---|
| CLI flag | `--otelVerbose` |
| Environment | `BROWSERHIVE_OTEL_VERBOSE` |
| Config file | `"otelVerbose"` |
| Type | a boolean: 'true', 'false', '1', '0', 'yes' or 'no' |
| Default | `false` |
| Notes | restart required |

<a id="otelTraceUrlTemplate"></a>
### `otelTraceUrlTemplate`

Dashboard deep-link template for a trace; {trace_id} is substituted. Used only by the dashboard.

| Property | Value |
|---|---|
| CLI flag | `--otelTraceUrlTemplate` |
| Environment | `BROWSERHIVE_OTEL_TRACE_URL_TEMPLATE` |
| Config file | `"otelTraceUrlTemplate"` |
| Type | a non-empty string |
| Default | unset |
| Examples | `https://grafana.local/explore?traceId={trace_id}` |
| Notes | runtime-adjustable |