Usage

birdpal [--sync] [--synclocal DIR] [--update] [--triggerID] [--tags] [--gps LAT,LON] [--immichalbum NAME]
        [--full] [--batchsize N] [--maxbatches N] [--tmpdir DIR] [--dry-run]

Give at least one of --sync, --synclocal, --update and --triggerID. You can combine them. Progress goes to stderr, with no timestamps (systemd and cron add their own).

Credentials

Each credential flag has an environment variable. birdpal uses the variable when you do not give the flag. A flag wins over its variable.

Variable Flag
BIRDPAL_BBEMAIL --bbemail
BIRDPAL_BBPASSWD --bbpasswd
BIRDPAL_IMMICHSERVER --immichserver
BIRDPAL_IMMICHKEY --immichkey
BIRDPAL_IMMICHALBUM --immichalbum

Use the variables for scheduled runs. Flags are visible to other users of the machine in ps and stay in your shell history. Keep the variables in a file only you can read, for example ~/.config/birdpal/birdpal.env (chmod 600), one NAME=value per line. The systemd units load that file.

Immich API key

Give the key only these permissions:

Permission Needed for
asset.upload uploads and the checksum check
asset.update description, capture time and GPS
asset.read recommended: finds media already in Immich by file name, so birdpal does not download them again, and checks every write at the end of the run
user.read optional: shows which account the key belongs to
album.read, album.create, albumAsset.create only with --immichalbum
tag.create, tag.asset only with --tags

Warning: never give a key "all" permissions. Full-scope Immich API keys are a known privilege-escalation risk (GHSA-237r-x578-h5mv, CVSS 7.2).

Modes

Mode What it does
--sync Collects waiting postcards, then reads the full media catalog, newest first. Uploads the media that Immich does not have, with description, capture time, GPS and tags. Files the media in --immichalbum.
--update Rewrites description, capture time, GPS and tags on media that are already in Immich. Use it after you change options, or to pick up names that Bird Buddy found later.
--synclocal DIR Collects waiting postcards, then saves the media that the folder does not have, each with an XMP sidecar. See Save to a folder.
--triggerID Triggers Bird Buddy's identification on every postcard in the inbox and records the confidence that Bird Buddy reports. Waits about 5 seconds per new identification.

Options

Option What it does
--tags Tags each asset with Bird Buddy/Species/<name> (Unidentified when Bird Buddy has no name), Bird Buddy/Feeder/<feeder name> and Bird Buddy/City/<city>. Immich shows these as a tag tree.
--gps LAT,LON Sets this location, in decimal degrees, on each asset, so the media show on Immich's map. Bird Buddy reports only a city name, so you give the coordinates.
--immichalbum NAME With --sync: puts every synced asset in this album, and creates it if it is missing. The name must match exactly.
--full Reads every batch. Without it, birdpal stops after the first batch with nothing new to upload, because everything older is already in Immich. Use it for the first run and for a regular full refresh.
--dry-run Reads Bird Buddy and Immich and prints would … lines, but changes nothing in Bird Buddy, Immich or the --synclocal folder.
--batchsize N Media per batch. Default 100, about 70 MB of temporary files.
--maxbatches N Stops after N batches. Default 0, no limit. Use it for test runs.
--tmpdir DIR Folder for the temporary files of one batch. Default $TMPDIR, or /tmp. The folder must exist. birdpal makes its own subfolder there and deletes it at the end of the run.
--version Prints the version and exits.

Save to a folder

--synclocal DIR saves the media into a folder, the same way --sync sends them to Immich. Each file keeps the name it gets in Immich (birdbuddy-<media id>.jpg or .mp4). Next to it, an XMP sidecar (<file>.xmp) holds the description, capture time, and the --gps location and --tags tags. Immich and digiKam read these sidecars. The file's modified time is the capture time.

  • --synclocal DIR alone does not use Immich, so the Immich credentials are not needed.
  • --sync --synclocal DIR does both in one run and downloads each file once.
  • With --update, files already in the folder get a fresh sidecar.
  • Files already in the folder are skipped, and --full works the same way as for Immich. The folder is the only state.
  • Files are written to a hidden temporary name and then renamed. A run never leaves half a file, and two runs can use the same folder at the same time.

Exit codes

Code Meaning
0 The run finished and nothing failed.
1 One or more items failed, or a hard error stopped the run (login, Immich check, album). The next run tries the failed items again.
2 Usage error: a flag or a credential is missing or wrong.