Run

Start the engine, verify it's alive, create your first campaign.

Start

Binary

# Minimal — no auth, in-memory only (dev)
banditdb

# With persistence and a single admin key
DATA_DIR=/var/lib/banditdb BANDITDB_API_KEYS=secret=admin banditdb

# Full production flags
DATA_DIR=/var/lib/banditdb \
BANDITDB_API_KEYS="admin-key=admin;app-key=writer;dash-key=reader" \
BANDITDB_CHECKPOINT_INTERVAL=5000 \
BANDITDB_MAX_WAL_SIZE_MB=100 \
LOG_FORMAT=json \
PORT=8080 \
banditdb

Docker Compose

docker compose up -d          # start in background
docker compose logs -f        # follow logs
docker compose down           # stop

Verify

curl http://localhost:8080/health
# {"status":"ok","version":"2.0.0","features":["neural"]}

/health is public and deliberately carries no campaign data — it sits outside the auth layer, so exposing campaign IDs there would leak the tenant list. Per-campaign entropy lives at /health/detail, which requires a reader key:

curl -H "X-Api-Key: $KEY" http://localhost:8080/health/detail
# {"status":"ok","version":"2.0.0","features":["neural"],
#  "campaigns":{"prices":{"entropy":0.82,"status":"ok"}}}

features lists the build flags. An empty list means a plain build: neural algorithms are unavailable and campaigns requesting them are rejected at creation.

Status values:

StatusHTTPMeaning
ok200All campaigns healthy, WAL writing normally.
degraded200One or more campaigns have entropy collapse. Service still running — data quality issue only.
degraded: wal unavailable503WAL writer failed. Predictions still served from memory but nothing is persisted. Treat as a service failure.

Logs

# Human-readable (default)
banditdb

# Structured JSON for log aggregators (CloudWatch, Datadog, Splunk)
LOG_FORMAT=json banditdb

Key log lines to watch on startup:

INFO banditdb: recovered 3 campaigns from checkpoint (offset=48291)
INFO banditdb: replayed 142 WAL events
INFO banditdb: listening on 0.0.0.0:8080

If checkpoint recovery fails the engine exits with a clear error rather than starting in a broken state. Check DATA_DIR permissions and that checkpoint.json is not corrupt.

First Campaign

# Create a campaign
curl -s -X POST http://localhost:8080/campaign \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: your-secret-key" \
  -d '{
    "campaign_id": "homepage-hero",
    "arms": ["variant_a", "variant_b", "variant_c"],
    "feature_dim": 4,
    "alpha": 1.0
  }'

# Confirm it exists
curl -s http://localhost:8080/campaigns \
  -H "X-Api-Key: your-secret-key"

Checkpoint and Stop

# Flush WAL, export Parquet, rotate — do this before stopping
curl -s -X POST http://localhost:8080/checkpoint \
  -H "X-Api-Key: your-secret-key"

# Then stop
docker compose down   # or kill the process

Always checkpoint before a planned shutdown. The WAL preserves everything since the last checkpoint, but checkpointing first keeps the WAL short and makes the next startup faster.