Hub process mode: full (single process), api (HTTP + WebSocket only, scalable), dispatcher (background workers only, single instance)
API_PORT
3000
HTTP listen port (internal)
JWT_SECRET
required
Secret for signing JWT session tokens
PLATFORM_ADMIN_EMAILS
—
Comma-separated emails for platform admin access
HUB_INTERNAL_API_KEY
—
Backwards-compatible machine access key
MFA_ENCRYPTION_KEY
—
32-byte hex key (openssl rand -hex 32) used to AES-256-GCM-encrypt stored TOTP secrets. Required once MFA is enrolled — rotating it invalidates every existing TOTP and forces re-enrollment. Without it, MFA features fail-closed at boot.
WEBAUTHN_RP_ID
derived
WebAuthn Relying Party ID (must match the eTLD+1 the user logs in on). Defaults to BNG_APP_FQDN.
WEBAUTHN_RP_NAME
BirdNET-NG
Friendly display name shown by browser passkey prompts.
WEBAUTHN_ORIGIN
derived
Full origin URL passed to WebAuthn verification. Defaults to https://${BNG_APP_FQDN}.
Configured in Platform Settings page, stored in platform_settings table.
Setting
Default
Description
allow_self_registration
true
Users can register without invite
allow_tenant_creation
false
Logged-in users can create tenants
allow_invite_links
true
Admins can generate invite links
image_download_delay_seconds
0 (auto)
Delay between Wikipedia image downloads. 0 derives from authenticated/unauthenticated rate tier
wikimedia_access_token
—
OAuth 2.0 token for Wikimedia API (raises rate limit from 500 to 10 000 req/hr)
wikimedia_contact_email
—
Contact email for Wikimedia User-Agent header
inaturalist_enabled
false
Opt-in fallback for gallery extras when Wikipedia is exhausted (v0.29+)
image_license_filter
["cc0","cc-by","cc-by-sa"]
License codes accepted by iNaturalist fetches; admin can widen to cc-by-nc / cc-by-nc-sa / cc-by-nc-nd. Photos with no license_code (= all rights reserved) are always rejected (v0.29+)
species_extra_images_count
5
Gallery extras per species beyond the primary. No upper bound; 0 disables extras (v0.29+ removed the hard 20 cap)
audio_storage_cap_gb
50
Soft cap (GB). When total usage crosses, next sweep purges oldest unprotected audio
audio_storage_hard_cap_gb
60 (= soft × 1.2)
Hard cap (GB). Same eviction policy as soft pass — protected (keep-best + pinned) audio is never auto-deleted (v0.29 correctness pass)
audio_retention_days
30
Delete non-keep-best audio older than this
keep_best_per_species
10
Top-N detections by confidence per species, never auto-deleted
silent_chunk_retention_hours
6
Purge chunks with 0 detections after this many hours
apk_keep_last_n
5
Keep the N most recent APK builds in mobile_releases; older ones drop on next sweep
retention_enabled
false
Run scheduled retention sweeps every 6h
inference_mode
single
single = default model only / compare = also run enabled non-default models on sampled chunks (writes to shadow_detections)
inference_compare_sample_rate
10
Percentage of chunks routed through compare mode (1–100)
dismissed_catalog_ids
[]
Catalog template IDs admin has hidden via the × button