Listenbrainz (Endpoint)
This Source enables multi-scrobbler to accept scrobbles from outside applications as if it was a Listenbrainz server.
If your service/player has a “Scrobble to Listenbrainz” feature and there is an option to set the Listenbrainz URL then multi-scrobbler can accept scrobbles from that service/player by imitating a real Listenbrainz server.
Standard Base URL
Section titled “Standard Base URL”In most scenarios you should use one of the following as the base URL when configuring your service to scrobble to multi-scrobbler:
-
http://:9078 -
http://:9078/1/
Standard Endpoints
Multi-scrobbler emulates some Listenbrainz API endpoints to ensure client compatibility.
Most importantly, the scrobble endpoint is:
http://YOUR_MS_DOMAIN/1/submit-listensAll available endpoints are found in the API documentation section Listenbrainz Ingress.
Most Listenbrainz clients require an Authentication Token to be provided during setup. This value can be anything you want but ensure you use the same value for token (ENV LZE_TOKEN) in your configuration for this Listenbrainz Endpoint Source.
If your service does not require a token, or does not let you set one, then do not configure it for this Source either.
Multiple Sources
Section titled “Multiple Sources”If you need configure more than one Listenbrainz Endpoint Source then MS can differentiate scrobbles based on Token so that you can use the same, standard base URL for many users.
However, if you cannot configure multiple tokens for your scenario you may also use a URL Slug to tell MS which Source belongs to a specific user. This is not a common scenario and should only be used if Token configuration is not sufficient or not possible.
Different URL Base (Slug)
When a slug is defined in ENV/File config MS will listen for listenbrainz submit-listens requests using the slug as the base route path. Example:
LZE_SLUG=foobarMS will accept requests for submit-listens (scrobble submissions and now playing) at
http://YOUR_MS_DOMAIN/api/listenbrainz/foobarhttp://YOUR_MS_DOMAIN/api/listenbrainz/foobar/submit-listensSee API documentation for the slug endpoint for more information.
Setup for Popular Apps
Section titled “Setup for Popular Apps”Navidrome
Section titled “Navidrome”Set the ListenBrainz.BaseURL (env ND_LISTENBRAINZ_BASEURL) to http://
Music Assistant
Section titled “Music Assistant”Music Assistant is an open source audio library manager that is commonly integrated into Home Assistant.
- In your Music Assistant UI navigate to Settings -> Plugins
- Click Add a plugin
- Add ListenBrainz Scrobbler
- In the ListenBrainz Scrobbler configuration screen:
- Save the configuration and you are ready to scrobble
To troubleshoot any errors, and assuming you are using Home Assistant, view the Logs in the Music Assistant Add-ons. Please include these logs in any reported issue.
TIDAL Hi-Fi
Section titled “TIDAL Hi-Fi”TIDAL Hi-Fi is a web version of TIDAL packaged as a desktop application. The desktop implementation enables additional features not available in the web-only player, including activity tracking and scrobbling.
Hi-Fi has its own documentation on how to setup Multi-Scrobbler. The instructions below are based off their docs.
Hi-Fi recommends using the non-standard URL scenario.
Create a Listenbrainz Endpoint Source config that includes both a Token and a Slug.
services: multi-scrobbler: # ... environment: # ... - LZE_TOKEN=tidal-hifi-scrobbles-2025 - LZE_SLUG=tidal[ { "name": "tidal-hifi-endpoint", "data": { "token": "tidal-hifi-scrobbles-2025", "slug": "tidal" } }]{ "sources": [ { "name": "tidal-hifi-endpoint", "type": "endpointlz", "data": { "token": "tidal-hifi-scrobbles-2025", "slug": "tidal" } } ]}Then, follow the steps to enable and configure Listenbrainz in TIDAL Hi-Fi Settings outlined in the Hi-Fi docs.
In those settings, ensure that:
- the ending of the API URL you set matches the
slugyou configured above EXslug=tidal=>http://localhost:9078/api/listenbrainz/tidal - the token you configured above matches the User Token you set in Hi-Fi
Troubleshooting URL
Section titled “Troubleshooting URL”If you think your service should be able to use the standard base URL but it is not working follow these steps before trying the the base URL Slug.
Verify URL Format
Section titled “Verify URL Format”Some service may require http/https in the URL format (http://) while others may not (). Check the docs for your service to see if they specify this or have an example. Try both versions, if possible, to see if one works.
Some Services Require HTTPS
Some services that can scrobble to a custom Listenbrainz URL may require the URL to have a real domain (example.com) and/or use SSL (https://). In this case you should setup multi-scrobbler behind a reverse proxy to support this functionality.
Is MS is Reachable?
Section titled “Is MS is Reachable?”Verify that MS can be accessed by your service, or from the same host as the service is running. See the FAQ for guidance on troubleshooting ingress connection issues.
Service Logging
Section titled “Service Logging”If you service has accessible logging, check to see if it outputs the URL it is trying to reach when authenticating the Listenbrainz account/user, or trying to make a scrobble request.
If you decide to report this issue, please include this logging in your issue.
Configuration
Section titled “Configuration”Artist Extraction and Matching
The Listenbrainz listens payload has many fields of varying granularity: (See OpenAPI Spec listensForUser_payload_listens_inner schema).
Relevant to MS, an LZ listen can contain one or more, different, artist fields that contain varying amounts of rich data, not all of which are guaranteed to be reliable.
Artist Fields and Assumptions
- Reported by the LZ Client
track_metadata.artist_name- a single string with all artists likeFoo and Bar feat. Cool Guytrack_metadata.additional_info.artist_names- a list of artist names like['Foo','Bar','Cool Guy']track_metadata.additional_info.artist_mbids- a list of artist MBIDs
- Reported by the LZ Client or LZ Server
track_metadata.mbid_mapping.artist_mbids- a list of artist MBIDstrack_metadata.mbid_mapping.artists- a list of artist objects like{artist_credit_name: 'Cool Guy', join_phrase: 'feat.', artist_mbid: '...'}
All of these fields, other than track_metadata.artist_name, are optional. Also, critically, these two assumptions apply:
mbid_mapping.*is usually only reported by a Listenbrainz Server but can also be provided by a LZ Client.- When LZ reports
mbid_mapping.*this is because it “matched” your payload dataartist_nameetc… with a Musicbrainz recording.- LZ does not provide a confidence metric to tell you how likely this mapping is actually correct
For MS to be as accurate as possible for things like deduplicating scrobbles and providing good data to scrobble enhancements it needs artist data to be as granular as possible since different Clients and Sources can report artists in various forms.
Because the LZ payload data can be so ambiguous MS processes LZ payload data through a more rigorous form of the Native Stage to try to extract, and match, artist data from all the fields mentioned above. In this case, more rigor => MS only modifies artist data when it has very high confidence it matches the original data well, backed by 25+ tests.
It also enables “smarter” decisions about LZ Source data that includes mbid_mapping because it’s possible the matched mappings do not actually align with the data you submitted: MS does string comparisons against these and if they are not highly aligned it falls back to the less-rich additional_info and artist_name fields instead of using the mismatched mbid_mappings.
This additional processing is enabled by default because most users benefit from this strict matching and corrections.
However, there are usecases where you may not want this additional processing to occur such as:
- You know your Listenbrainz Endpoint/Source has high quality matches/submission data that must stay byte-equivalent or contains many already-corrected for edge cases you don’t want MS to modify
- You are using MS to forward Now Playing data with
artist_namefields formatted exactly as you already want them, which MS should not change - You are transferring scrobbles between LZ servers and want byte-equivalant scrobbles for data preservation/archiving
If your usecase meets this scenario, or you just generally don’t want MS doing anything with artists, you can disable artist extraction using one of these options in your config:
- File/AIO - use
"options": {"extractArtists": false } - ENV - use
LZE_EXTRACT_ARTISTS=false
Configuration Type
This is configuration for the ENV Config Type.
| Environmental Variable | Type | Default | Description |
|---|---|---|---|
LZE_ID |
string | A globally unique ID EX myComponentId |
|
LZE_NAME |
string | Value of LZE_ID |
A vanity name EX My Cool Component |
LZE_ENABLE |
boolean | true | Should this component be used? |
LZE_SLUG |
string | When using multiple sources without tokens, or not using a standard base URL, this is the URL base path that should be used to identify scrobbles for this source | |
LZE_TOKEN |
string | If an LZ submission request contains this token in the Authorization Header it will be used to match the submission with this Source | |
LZE_USERNAME |
string | The listenbrainz “username” to associate with this Source | |
LZE_EXTRACT_ARTISTS |
boolean | true | Tries to extract and match artists from comma-delimited listen data. Set to false to use listen data as-is (will likely lose fidelity!) |
Bold/Italic = Required
Config Structure
This displays the structure of the File Configuration for a endpointlz type Source with all possible properties, their shape, and descriptions/types. Use this to understand how to write a valid config.
Config Example
This displays an example config file of a endpointlz Source File Configuration that adheres to the shown Config Structure.
- text mode lets you edit the JSON directly.
- tree mode gives you a guided point-and-click editing experience that always keeps the JSON syntax valid.
Both modes validate that the configuration is correct. Any errors show up as squiggly lines.
After you finish editing, switch to text and then copy all text to get a completed config.
Config Example Mobile Experience
This displays an example config file of a endpointlz Source File Configuration that adheres to the shown Config Structure.
The example config file editor is meant for a larger screen experience so only the read-only example is shown. Please use this site on a tablet/laptop/desktop to enable file editor features.
[ { "id": "myLzNavidrome", "name": "LZ for Navidrome", "data": { "token": "myToken" }, "enable": true }]Config Structure
This displays the structure of the all-in-one (config.json) configuration with all possible properties, their shape, and descriptions/types. Use this to understand how to write a valid config.
Select the endpointlz type from the respective sources node below, then expand it.
Config Example
This displays an example config file of a all-in-one (config.json) configuration that includes a endpointlz Source that adheres to the shown Config Structure.
- text mode lets you edit the JSON directly.
- tree mode gives you a guided point-and-click editing experience that always keeps the JSON syntax valid.
Both modes validate that the configuraion is correct. Any errors show up as squiggly lines.
After you finish editing, switch to text and then copy all text to get a completed config.
Config Example Mobile Experience
This displays an example config file of a all-in-one (config.json) configuration that includes a endpointlz Source that adheres to the shown Config Structure.
The example config file editor is meant for a larger screen experience so only the read-only example is shown. Please use this site on a tablet/laptop/desktop to enable file editor features.
{ "sources": [ { "type": "endpointlz", "id": "myLzNavidrome", "name": "LZ for Navidrome", "data": { "token": "myToken" }, "enable": true } ]}