Settings & Detection
The admin area lives under /admin. The Settings page (/admin/settings) persists everything you change into the SQLite settings table.
When a change takes effect
Every field on the page carries a small badge: Applies immediately (the part of the station that uses it reads the stored value again on its own, typically within about half a minute) or Applies after restart (the value is read once, when the station starts). The badge is drawn from one table in the code, and a test fails if a field on the page lacks one, so the page cannot disagree with itself.
When you have saved something that is still waiting for a restart, a banner at the top of the page lists which settings and offers the Restart button. Under a service manager (systemd, Docker’s restart policy) the button stops the process and the manager starts it again. A station started by hand restarts itself in place with the same arguments; if neither is possible the button says so instead of stopping the station and leaving it stopped.
The bird-identifying model
At the top of Settings → Capture (and as step 2 of the setup wizard), the Bird-identifying model panel says whether the classifier the station needs is installed. If it is missing, Install downloads it (checked against a pinned SHA-256, with a progress bar and a free-space check first) and the panel then offers the restart that loads it. This is the same installer as --install-model; the program, not the browser, does the download.
Numbers the page refuses
A number typed into a field is checked against the range the station actually accepts before it is saved, and the message names the range. The same bounds apply to PUT /api/v2/settings and, as warnings, to --doctor for the config file: frequency shift, sunrise/sunset recording offsets, notification cooldown, dead-man hours, clip retention days, files kept per species, disk purge threshold, extraction length, rare-species window, stream retention and size, SMTP port, email cooldown and clip loudness target. (They are warnings, not errors, in --doctor because an error makes the station fall back to its last-good configuration file.)
How a setting is resolved
Most settings can be supplied three ways — a CLI flag (or its BIRDNET_*
environment variable), a line in birdnet.conf, and this page. When more than
one is set, the station resolves them in this order:
- An explicit CLI flag or
BIRDNET_*variable — if you passed it, it wins. - This page — what you save here beats the config file.
birdnet.conf- The built-in default.
So a Docker station pinned with -e BIRDNET_SEGMENT_DURATION=30 keeps that value
no matter what the form says, while a bare-metal station that never passes the
flag is governed entirely by this page.
Settings not on this page
Two things are deliberately configured elsewhere in the browser:
- The admin password. It is stored as an Argon2id hash in the accounts
database, seeded from the
CADDY_PWDenvironment variable — never as a settings row. See Remote Access & Security. - Per-source audio properties (channels, sample rate, gain, RTSP transport). Each microphone or stream carries its own, on Audio & Microphones.
A handful of settings are file-only on purpose, each for a stated reason — secrets that must not live in the database a backup copies, listen address and TLS (a typo locks you out of the page you would fix it on), and similar. Where to change it lists every setting, the browser page that owns it, and for the exceptions why.
Detection
- Confidence threshold — the minimum score a detection must clear to be logged (default
0.70, BirdNET-Pi’s own; it was 0.75 up to v0.17.1). Raise it to cut false positives; lower it to catch faint calls. - Per-species thresholds — override the global threshold for individual species (useful for a noisy local mimic, or to be stricter about a rare bird).
- Sensitivity (0.5–1.5) — the BirdNET sensitivity parameter (also
SENSITIVITYinbirdnet.conf). It only affects BirdNET V2.4 models; the BirdNET+ V3.0 preview ignores it. It means what it means in BirdNET-Pi and BirdNET-Analyzer, so a value carried over from BirdNET-Pi reproduces that station’s confidence scores: the model’s raw score is passed through a sigmoid with slopeclamp(2 − value, 0.5, 1.5). A higher value therefore flattens the curve, and at any confidence threshold above 0.5 (all the usual ones) it gives fewer detections, not more. birdnet-go’ssensitivityis the slope itself, so to carry a birdnet-go value across, enter2 − value. - Human-sound privacy — a station near a house will sometimes hear speech, and two independent rules keep it out of the log and the saved clips: a window, and the windows either side of it, are suppressed when either fires. Each is a field in the Detection section.
- The rank rule, Privacy Rank (
PRIVACY_RANK, default10,0= off, up to12000), is BirdNET-Pi’s own: it fires when a human class (speech, whistling, other human sounds) is among the model’s N highest-scoring classes, read before the confidence threshold. It is on by default, including on a station upgraded from a release that had no such rule and that sets neither key;10is BirdNET-Pi’s behaviour. A larger number drops more windows. It is a whole number, a count of classes and not a confidence:0.02is refused rather than cut to0(which would switch the rule off), and so are10%,1,000, a negative number and anything above12000, with a message that names the range. Leave the field blank to fall back to the default. The same bounds apply to the config file (--doctorchecks them) and toPUT /api/v2/settings. A flag or variable other than10(--privacy-rank,BIRDNET_PRIVACY_RANK) still beats the page. - The confidence rule, Privacy Threshold (
PRIVACY_THRESHOLD, default0= off, typically 0.01–0.03), fires when the model’s confidence for a human class reaches the value. It shares its name with a BirdNET-Pi key that is on a different scale, so a BirdNET-Pi value does not carry across; Same audio, same detections has the conversion.
- The rank rule, Privacy Rank (
- Species-frequency filter — uses your location and the week of the year to down-weight birds that shouldn’t be present, with a configurable
SF_THRESH. To see what it admits, and why a particular bird is held back, open Why isn’t a bird heard here? on the Species page. - Noise filter (
NOISE_THRESHOLD,NOISE_CLASSES) — optionally discards a window in which a watched non-bird class (by defaultDog) scores at or above the threshold. Off by default; see Tuning §7. There is no filter that drops rainy or windy audio before it reaches the model. - Analysis overlap (0–2.9 s) — how far consecutive analysis windows (3 s for V2.4, 4.5 s for the V3.0 preview) overlap. Higher catches calls that straddle a window boundary, and costs CPU in proportion:
2.0triples the inference work per recording. - Repeat confirmation — record a species only when enough of the windows within six seconds heard the same thing. A real bird sings across several windows; a car door or a squeak of the mount usually fires in exactly one. It needs the overlap above — with none, there is only one other window to agree with, and each option in the dropdown prints the overlap it needs. Off by default. See Tuning.
Species & quarantine
Rare-bird quarantine rules decide which detections are held for manual review instead of being logged automatically — see the review queue. You can also maintain per-species allow/exclude lists and image overrides here.
Allow and exclude lists
The lists under Settings → Capture → Species (/station/capture#species; the old /admin/species redirects there) decide which birds the station records at all:
- Exclude — these species are never recorded. Nothing is written to the database, no notification is sent, and nothing is uploaded to BirdWeather. Use it for a persistent local false positive, or for a species you would rather not log.
- Allow — when non-empty, only these species are recorded.
- Always allowed (whitelist) — species the species-occurrence filter would
hold back as unlikely for your location and week are recorded anyway. This is
BirdNET-Pi’s
whitelist_species_list.txt, with its meaning: it exempts a species from the occurrence threshold and from nothing else. A species on the exclude list stays excluded, one missing from a non-empty allow list stays out, and it does nothing on a station with no location set (nothing is held back there). It is for the one or two birds you know visit; lowering the occurrence threshold under Detection is the broader tool.
Enter either the common name or the scientific name; both work, and case and
surrounding spaces don’t matter. Changes take effect within about half a minute
— no restart. /admin/species/test previews the decision for every species your
station has seen, using the same code the detection path runs, so what it shows
is what will happen.
An allow list whose entries match no species this model knows is ignored, and a warning is logged, rather than being taken literally and suppressing everything.
Species storage
Settings → Capture → Species → Species storage (/admin/species/manage) is one row per species this station has ever recorded, with its detection count, how many still have audio on disk, how many you have locked, and when it was last heard. It exists for one recurring situation: a squeaky gate has produced four thousand Eurasian Wrens and you want them gone.
Three actions per row, each confirmed:
| Action | What it does | What survives |
|---|---|---|
| Exclude | Stops the species being recorded from now on | Everything already stored |
| Delete detections | Removes its rows | Nothing — this cannot be undone |
| Delete clips | Reclaims the audio files | The detections, so the record of what was heard stays intact |
Locked detections are never touched by any of them. The row shows the locked count before you press anything, and the result tells you how many were kept — so a species you deleted that still has two detections is explained rather than looking like a bug. Unlock those first if you meant to include them.
Measure adds up the species’ clips on disk. It is a separate button rather than a column because it has to stat every file, and doing that for every species on every page load would make the page take many seconds to open on an SD card.
All three actions are written to the audit log.
Species photographs
Each species page shows a photograph, cached on disk so the station works offline after the first fetch. Three sources are available.
Wikipedia (the default) needs no key and covers most species. For a long tail it has no photograph at all, and for many others it has a museum skin, an egg, or a range map rather than a living bird.
AviCommons (IMAGE_PROVIDER=avicommons) needs no key. AviCommons is a library of cropped, oriented Creative Commons bird photographs made to be embedded. It is tried first and Wikipedia fills in behind it. The station downloads AviCommons’ one JSON index (1.6 MB, which its README asks to be fetched once and not on each page load) and keeps it in the image cache folder for 30 days, then each photograph once. Only the CC0, CC BY and CC BY-SA images are used, the same rule as Flickr below: of the index’s 10,185 images (checked 2026-10-21) 2,620 qualify, the rest are NonCommercial. Against the 6,522 species of the BirdNET V2.4 labels that is 1,628 species (25 %) with an AviCommons photograph, and the rest keep Wikipedia’s. Each photograph is shown with its photographer, its licence and a link to AviCommons. The project’s repository declares no licence of its own; the terms are per image, in the index.
Flickr searches Flickr first and falls back to Wikipedia when Flickr has nothing, so turning it on can only add coverage — it never leaves a species blank that Wikipedia could have filled. It needs a free API key from Flickr’s app page:
IMAGE_PROVIDER=flickr
FLICKR_API_KEY=your-key-here
Showing your own photographs
Set FLICKR_FILTER_EMAIL to the email address on your Flickr account and the
search is restricted to your own photostream — your pictures of the birds your
own station heard. Wikipedia still fills in the species you have not
photographed, which is the whole point of the fallback: a filtered stream has a
few dozen species in it, not nine thousand.
IMAGE_PROVIDER=flickr
FLICKR_API_KEY=your-key-here
FLICKR_FILTER_EMAIL=you@example.com
Licensing
Only the Creative Commons licences that permit commercial use are requested — CC BY, CC BY-SA, CC BY-ND, CC0, Public Domain Mark, Flickr Commons, and US Government works. Your station’s page may end up published; the station cannot know whether that counts as commercial, so it asks only for photographs where the answer does not matter.
Attribution is not optional under CC BY and CC BY-SA, so every photograph is shown with its photographer’s name and a link to the Flickr page carrying the licence terms. A photograph Flickr returns with no photographer named is skipped rather than shown uncredited.
Notes
- Switching provider does not re-download anything: the cache is keyed on the species name alone, so images already on disk are kept.
- A wrong or revoked API key is reported in the log and the station falls back to Wikipedia rather than showing nothing.
FLICKR_API_KEYis masked in support bundles, and so is the local part ofFLICKR_FILTER_EMAIL(you@example.combecomes***@example.com) — the domain stays because it is the diagnostic half.- Neither source is used at all in offline mode, or when the image cache is
disabled with an empty
IMAGE_CACHE_DIR.
Spectrograms
Two settings under System & Display change how every spectrogram is drawn, and a change shows on the next image, with no restart (the answer is revalidated rather than cached for an hour, so a browser that already has the old picture asks again):
- Spectrogram colours — Viridis (blue to yellow, what earlier versions drew and the default), Magma and Inferno (black to pale or bright yellow), Grey (quiet is black) and Grey, inverted (quiet is white, the look of a printed figure). Louder is always lighter, so the order survives a grey print; a unit test holds CIELAB lightness monotonic for every map. Magma and Inferno are matplotlib’s tables (CC0).
- Spectrogram dynamic range — 60, 80 (the default), 100 or 120 dB. Cells more than this far below the loudest in the clip are drawn as the floor. A smaller range gives more contrast and lets faint calls sink into the background. birdnet-go offers 80, 100 and 120 (
dynamicrange); 60 is added here.
There is no gain setting, because the image is stretched between its own quietest and loudest cell, so a gain would change nothing. The live spectrogram on Recordings is drawn by the browser and keeps its own colours.
Your picture on the Today page
BirdNET-Pi’s CUSTOM_IMAGE and CUSTOM_IMAGE_TITLE. Set Today page picture (file) to the full path of a PNG, JPEG, GIF or WebP file and Picture title to its heading, and the Today page shows it between the day strip and the log. A webcam works the same way: something on the station keeps the file current (for example a cron job running ffmpeg -i rtsp://camera/stream -frames:v 1 -y /home/pi/camera/latest.jpg every minute) and the page checks it every ten seconds while the tab is visible, fetching it again only when the file’s size or time changed. BirdNET-Pi re-reads it every second and inlines it; this does one conditional request in ten seconds, which is easier on a Raspberry Pi.
The file is held to what a picture is: a regular file, at most 8 MiB, a PNG, JPEG, GIF or WebP by its first bytes whatever its name says (so a path typed with a slip, or /etc/passwd, shows nothing; SVG is refused because it can carry script). If the file cannot be read the block says so and keeps trying. It is a block like the others: hide or move it under Today Page Layout. Only a file path is supported, as upstream; a camera that only offers a URL needs the snapshot saved to a file first.
This is not custom_image_dir, which replaces one species’ photograph.
Other categories
The Settings sidebar also covers Location, Audio (see Audio & Microphones), Notifications & Email (see Notifications & Integrations), MQTT / Home Assistant, and System.
Data quality
The Quality dashboard (Settings → Data, /station/data#quality; the old /admin/quality redirects there) summarizes the health of your detection database — the confidence distribution, a 30-day confidence trend, an hourly quality profile, and a ranked list of low-confidence species that are good candidates for a stricter per-species threshold.