Configuration

lumen works with zero configuration. lumen.config.json in your project root (or the path in LUMEN_CONFIG) is for when you want to tune budgets, swap providers, or move the failure line.

The file

{
  "providers": {
    "keywords": "wikipedia-demand",
    "serp": "ddg-serp"
  },
  "severityOverrides": {
    "og-tags-missing": "warning"
  },
  "crawl": {
    "maxPages": 250,
    "maxDepth": 4,
    "maxDurationMs": 600000,
    "maxConcurrency": 5,
    "perHostMinDelayMs": 500
  },
  "failThreshold": "warning",
  "byok": {
    "pagespeed": "LUMEN_PSI_KEY",
    "crux": "LUMEN_CRUX_KEY",
    "openpagerank": "LUMEN_OPR_KEY"
  },
  "plugins": []
}

A missing file means full defaults. A malformed file, a non-object root, or an unknown key at a closed-vocabulary level is a ConfigError that lists the valid keys — lumen would rather refuse than guess what you meant.

Keys

KeyWhat it controls
providersprovider name per boundary (keywords, serp, pagespeed, crux, authority); unknown names are a config error listing the options
severityOverridesper-rule severity overrides by rule id
crawlbudgets: maxPages, maxDepth, maxDurationMs, maxConcurrency, perHostMinDelayMs
failThresholdlowest severity that fails a run: error | warning | info | off (default error)
byokenv-var NAMES for provider keys (values never enter the file)
pluginslocal plugin files implementing extra audit rules (Node-only)

Crawl defaults

BudgetDefaultNote
maxPages100hard-clamped at 10,000
maxDepth5link depth from the seed
maxDurationMs300,000wall-clock stop; the report is marked incomplete
maxConcurrency5global in-flight cap
perHostMinDelayMs250per-host politeness floor

Error behavior

  • Unknown config keys fail loudly with the list of valid keys — at any closed-vocabulary level.
  • Boundary inputs have defined behavior: non-http(s) URLs are rejected, oversized pages and sitemaps are capped and skipped with a reason, malformed robots.txt falls back to the conservative default, IDN hostnames are normalized.
  • Provider failures are typed and carry the provider name, after bounded retries with exponential backoff and jitter (Retry-After honored).
  • Interrupted runs produce a report labeled incomplete: true with a stop reason, safe to re-run without duplicated side effects.
  • Plugins are Node-only — dynamically loaded local rule files; they never load in the Worker.

Fetch safety & etiquette

All fetching goes through one guarded layer: http/https only, private / loopback / link-local targets refused, re-validated after every redirect hop, per-request timeouts. On the crawl side, robots.txt is respected by default (with a documented override if you own the site and insist), the User-Agent identifies lumen with a contact URL, sitemaps feed discovery, and each host is rate-limited. Treat other people’s servers the way you’d want your logs to look.

For provider keys and what each one sends, see providers & BYOK. For the rules all this feeds, see the rules reference.