Navidrome

Music config redirect tested — L1→L4

Point ND_LISTENBRAINZ_BASEURL at the sidecar — every play pays the artist, per listen.

What gets metered

a completed listen — Navidrome scrobbles each play to its configured ListenBrainz target; the sidecar speaks the ListenBrainz wire protocol (GET /1/validate-token, POST /1/submit-listens) and charges RATE per single listen (playing_now submissions are metered-and-skipped).

Attach surface — no fork

Navidrome's own config: ND_LISTENBRAINZ_BASEURL (default https://api.listenbrainz.org/1/) is redirected to the sidecar. Navidrome scrobbles to us natively — it can't tell the difference. Zero fork change, no proxy.

Quickstart

Run the sidecar, then redirect Navidrome's ListenBrainz target at it:

PLATFORM=navidrome RATE=100 \
MUSICBRAINZ_USER_AGENT="universal-paywall/0.1 (ops@example.com)" \
PAYER_WALLETS='{"<listenbrainz-token>":"0x…"}' \
CREATOR_WALLETS='{"<artist-mbid>":"0x…"}' \
FACILITATOR_URL=https://facilitator.example FACILITATOR_API_KEY=… \
npx up-integration

# in the Navidrome service environment:
ND_LISTENBRAINZ_ENABLED=true
ND_LISTENBRAINZ_BASEURL=http://up-sidecar:8410/1/

# in Navidrome: link ListenBrainz with the listener's token
# (the sidecar validates it and treats it as the payer key)

All values above are placeholders — supply your own facilitator, wallets, and rate. The shared prerequisites (a deployed StakeVaultFactory, a running facilitator, a wallet registry) are covered in the admin overview.

Verify

node scripts/e2e-navidrome-live-docker.mjs

Full loop against a live ghcr.io/navidrome/navidrome container: link a token, scrobble an MBID-tagged track, resolve the artist via live MusicBrainz WS/2, settle on anvil.

Notes & caveats

Links

← All integrations