ListenBrainz API

The ListenBrainz server supports the following end-points for submitting and fetching listens. All endpoints have this root URL for our current production site [1].

  • API Root URL: https://api.listenbrainz.org
  • Web Root URL: https://listenbrainz.org

Note: All ListenBrainz services are only available on HTTPS!

Reference

Core API Endpoints

POST /1/submit-listens

Submit listens to the server. A user token (found on https://listenbrainz.org/profile/ ) must be provided in the Authorization header! Each request should also contain at least one listen in the payload.

Listens should be submitted for tracks when the user has listened to half the track or 4 minutes of the track, whichever is lower. If the user hasn’t listened to 4 minutes or half the track, it doesn’t fully count as a listen and should not be submitted.

For complete details on the format of the JSON to be POSTed to this endpoint, see JSON Documentation.

Request Headers:
 
Status Codes:
Response Headers:
 
GET /1/validate-token

Check whether a User Token is a valid entry in the database.

In order to query this endpoint, send a GET request with the Authorization header set to the value Token [the token value].

Note

This endpoint also checks for token argument in query params (example: /validate-token?token=token-to-check) if the Authorization header is missing for backward compatibility.

A JSON response, with the following format, will be returned.

  • If the given token is valid:
{
    "code": 200,
    "message": "Token valid.",
    "valid": true,
    "user_name": "MusicBrainz ID of the user with the passed token"
}
  • If the given token is invalid:
{
    "code": 200,
    "message": "Token invalid.",
    "valid": false,
}
Status Codes:
POST /1/delete-listen

Delete a particular listen from a user’s listen history. This checks for the correct authorization token and deletes the listen.

The format of the JSON to be POSTed to this endpoint is:

{
    "listened_at": 1,
    "recording_msid": "d23f4719-9212-49f0-ad08-ddbfbfc50d6f"
}
Request Headers:
 
Status Codes:
Response Headers:
 
GET /1/user/(playlist_user_name)/playlists/collaborator

Fetch playlist metadata in JSPF format without recordings for which a user is a collaborator. If a playlist is private, it will only be returned if the caller is authorized to edit that playlist.

Parameters:
  • count (int) – The number of playlists to return (for pagination). Default DEFAULT_NUMBER_OF_PLAYLISTS_PER_CALL
  • offset (int) – The offset of into the list of playlists to return (for pagination)
Status Codes:
Response Headers:
 
GET /1/user/(playlist_user_name)/playlists/createdfor

Fetch playlist metadata in JSPF format without recordings that have been created for the user. Createdfor playlists are all public, so no Authorization is needed for this call.

Parameters:
  • count (int) – The number of playlists to return (for pagination). Default DEFAULT_NUMBER_OF_PLAYLISTS_PER_CALL
  • offset (int) – The offset of into the list of playlists to return (for pagination)
Status Codes:
Response Headers:
 
GET /1/users/(user_list)/recent-listens

Fetch the most recent listens for a comma separated list of users. Take care to properly HTTP escape user names that contain commas!

Note

This is a bulk lookup endpoint. Hence, any non-existing users in the list will be simply ignored without raising any error.

Status Codes:
  • 200 OK – Fetched listens successfully.
  • 400 Bad Request – Your user list was incomplete or otherwise invalid.
Response Headers:
 
GET /1/user/(user_name)/similar-users

Get list of users who have similar music tastes (based on their listen history) for a given user. Returns an array of dicts like these:

{
    "user_name": "hwnrwx",
    "similarity": 0.1938480256
}
Parameters:
  • user_name – the MusicBrainz ID of the user whose similar users are being requested.
Status Codes:
Response Headers:
 
GET /1/user/(user_name)/listen-count

Get the number of listens for a user user_name.

The returned listen count has an element ‘payload’ with only key: ‘count’ which unsurprisingly contains the listen count for the user.

Status Codes:
Response Headers:
 
GET /1/user/(user_name)/playing-now

Get the listen being played right now for user user_name.

This endpoint returns a JSON document with a single listen in the same format as the /user/<user_name>/listens endpoint, with one key difference, there will only be one listen returned at maximum and the listen will not contain a listened_at element.

The format for the JSON returned is defined in our JSON Documentation.

Status Codes:
Response Headers:
 
GET /1/user/(user_name)/similar-to/(other_user_name)

Get the similarity of the user and the other user, based on their listening history. Returns a single dict:

{
    "user_name": "other_user",
    "similarity": 0.1938480256
}
Parameters:
  • user_name – the MusicBrainz ID of the the one user
  • other_user_name – the MusicBrainz ID of the other user whose similar users are
Status Codes:
Response Headers:
 
GET /1/user/(playlist_user_name)/playlists

Fetch playlist metadata in JSPF format without recordings for the given user. If a user token is provided in the Authorization header, return private playlists as well as public playlists for that user.

Parameters:
  • count (int) – The number of playlists to return (for pagination). Default DEFAULT_NUMBER_OF_PLAYLISTS_PER_CALL
  • offset (int) – The offset of into the list of playlists to return (for pagination)
Status Codes:
Response Headers:
 
GET /1/user/(user_name)/listens

Get listens for user user_name. The format for the JSON returned is defined in our JSON Documentation.

If none of the optional arguments are given, this endpoint will return the DEFAULT_ITEMS_PER_GET most recent listens. The optional max_ts and min_ts UNIX epoch timestamps control at which point in time to start returning listens. You may specify max_ts or min_ts, but not both in one call. Listens are always returned in descending timestamp order.

Parameters:
  • max_ts – If you specify a max_ts timestamp, listens with listened_at less than (but not including) this value will be returned.
  • min_ts – If you specify a min_ts timestamp, listens with listened_at greater than (but not including) this value will be returned.
  • count – Optional, number of listens to return. Default: DEFAULT_ITEMS_PER_GET . Max: MAX_ITEMS_PER_GET
Status Codes:
Response Headers:
 
GET /1/latest-import

Get the timestamp of the newest listen submitted by a user in previous imports to ListenBrainz.

In order to get the timestamp for a user, make a GET request to this endpoint. The data returned will be JSON of the following format:

{
    "musicbrainz_id": "the MusicBrainz ID of the user",
    "latest_import": "the timestamp of the newest listen submitted in previous imports. Defaults to 0"
}
Query Parameters:
 
  • user_name (str) – the MusicBrainz ID of the user whose data is needed
Status Codes:
  • 200 OK – Yay, you have data!
Response Headers:
 
POST /1/latest-import

Update the timestamp of the newest listen submitted by a user in an import to ListenBrainz.

In order to update the timestamp of a user, you’ll have to provide a user token in the Authorization Header. User tokens can be found on https://listenbrainz.org/profile/.

The JSON that needs to be posted must contain a field named ts in the root with a valid unix timestamp. Example:

{
   "ts": 0
}
Request Headers:
 
Status Codes:
  • 200 OK – latest import timestamp updated
  • 400 Bad Request – invalid JSON sent, see error message for details.
  • 401 Unauthorized – invalid authorization. See error message for details.

Playlists API Endpoints

The playlists API allows for the creation and editing of lists of recordings

POST /1/playlist/create

Create a playlist. The playlist must be in JSPF format with MusicBrainz extensions, which is defined here: https://musicbrainz.org/doc/jspf . To create an empty playlist, you can send an empty playlist with only the title field filled out. If you would like to create a playlist populated with recordings, each of the track items in the playlist must have an identifier element that contains the MusicBrainz recording that includes the recording MBID.

When creating a playlist, only the playlist title and the track identifier elements will be used – all other elements in the posted JSPF wil be ignored.

If a created_for field is found and the user is not an approved playlist bot, then a 403 forbidden will be raised.

Request Headers:
 
Status Codes:
  • 200 OK – playlist accepted.
  • 400 Bad Request – invalid JSON sent, see error message for details.
  • 401 Unauthorized – invalid authorization. See error message for details.
  • 403 Forbidden – forbidden. The submitting user is not allowed to create playlists for other users.
Response Headers:
 
POST /1/playlist/(playlist_mbid)/item/delete

To delete an item in a playlist, the POST data needs to specify the recording MBID and current index of the track to delete, and how many tracks from that position should be moved deleted. The format of the post data should look as follows:

{
    "index": 3,
    "count": 2
}
Request Headers:
 
Status Codes:
  • 200 OK – playlist accepted.
  • 400 Bad Request – invalid JSON sent, see error message for details.
  • 401 Unauthorized – invalid authorization. See error message for details.
  • 403 Forbidden – forbidden. the requesting user was not allowed to carry out this operation.
Response Headers:
 
POST /1/playlist/(playlist_mbid)/item/move

To move an item in a playlist, the POST data needs to specify the recording MBID and current index of the track to move (from), where to move it to (to) and how many tracks from that position should be moved (count). The format of the post data should look as follows:

{
    "mbid": "<mbid>",
    "from": 3,
    "to": 4,
    "count": 2
}
Request Headers:
 
Status Codes:
  • 200 OK – move operation succeeded
  • 400 Bad Request – invalid JSON sent, see error message for details.
  • 401 Unauthorized – invalid authorization. See error message for details.
  • 403 Forbidden – forbidden. the requesting user was not allowed to carry out this operation.
Response Headers:
 
POST /1/playlist/(playlist_mbid)/item/add
POST /1/playlist/(playlist_mbid)/item/add/(int: offset)

Append recordings to an existing playlist by posting a playlist with one of more recordings in it. The playlist must be in JSPF format with MusicBrainz extensions, which is defined here: https://musicbrainz.org/doc/jspf .

If the offset is provided in the URL, then the recordings will be added at that offset, otherwise they will be added at the end of the playlist.

You may only add MAX_RECORDINGS_PER_ADD recordings in one call to this endpoint.

Request Headers:
 
Status Codes:
  • 200 OK – playlist accepted.
  • 400 Bad Request – invalid JSON sent, see error message for details.
  • 401 Unauthorized – invalid authorization. See error message for details.
  • 403 Forbidden – forbidden. the requesting user was not allowed to carry out this operation.
Response Headers:
 
POST /1/playlist/edit/(playlist_mbid)

Edit the private/public status, name, description or list of collaborators for an exising playlist. The Authorization header must be set and correspond to the owner of the playlist otherwise a 403 error will be returned. All fields will be overwritten with new values.

Request Headers:
 
Status Codes:
  • 200 OK – playlist accepted.
  • 400 Bad Request – invalid JSON sent, see error message for details.
  • 401 Unauthorized – invalid authorization. See error message for details.
  • 403 Forbidden – forbidden. The subitting user is not allowed to edit playlists for other users.
Response Headers:
 
POST /1/playlist/(playlist_mbid)/delete

Delete a playlist. POST body data does not need to contain anything.

Request Headers:
 
Status Codes:
Response Headers:
 
POST /1/playlist/(playlist_mbid)/copy

Copy a playlist – the new playlist will be given the name “Copy of <playlist_name>”. POST body data does not need to contain anything.

Request Headers:
 
Status Codes:
Response Headers:
 
GET /1/playlist/(playlist_mbid)

Fetch the given playlist.

Parameters:
  • playlist_mbid (str) – The playlist mbid to fetch.
  • fetch_metadata (bool) – Optional, pass value ‘false’ to skip lookup up recording metadata
Status Codes:
Response Headers:
 

Feedback API Endpoints

These API endpoints allow to submit and retrieve feedback for a user’s recordings

POST /1/feedback/recording-feedback

Submit recording feedback (love/hate) to the server. A user token (found on https://listenbrainz.org/profile/ ) must be provided in the Authorization header! Each request should contain only one feedback in the payload.

For complete details on the format of the JSON to be POSTed to this endpoint, see Feedback JSON Documentation.

Request Headers:
 
Status Codes:
Response Headers:
 
GET /1/feedback/recording/(recording_msid)/get-feedback

Get feedback for recording with given recording_msid. The format for the JSON returned is defined in our Feedback JSON Documentation.

Parameters:
  • score (int) – Optional, If 1 then returns the loved recordings, if -1 returns hated recordings.
  • count (int) – Optional, number of feedback items to return, Default: DEFAULT_ITEMS_PER_GET Max: MAX_ITEMS_PER_GET.
  • offset (int) – Optional, number of feedback items to skip from the beginning, for pagination. Ex. An offset of 5 means the top 5 feedback will be skipped, defaults to 0.
Status Codes:
  • 200 OK – Yay, you have data!
Response Headers:
 
GET /1/feedback/user/(user_name)/get-feedback-for-recordings

Get feedback given by user user_name for the list of recordings supplied. The format for the JSON returned is defined in our Feedback JSON Documentation.

If the feedback for given recording MSID doesn’t exist then a score 0 is returned for that recording.

Parameters:
  • recordings (str) – comma separated list of recording_msids for which feedback records are to be fetched.
Status Codes:
  • 200 OK – Yay, you have data!
Response Headers:
 
GET /1/feedback/user/(user_name)/get-feedback

Get feedback given by user user_name. The format for the JSON returned is defined in our Feedback JSON Documentation.

If the optional argument score is not given, this endpoint will return all the feedback submitted by the user. Otherwise filters the feedback to be returned by score.

Parameters:
  • score (int) – Optional, If 1 then returns the loved recordings, if -1 returns hated recordings.
  • count (int) – Optional, number of feedback items to return, Default: DEFAULT_ITEMS_PER_GET Max: MAX_ITEMS_PER_GET.
  • offset (int) – Optional, number of feedback items to skip from the beginning, for pagination. Ex. An offset of 5 means the top 5 feedback will be skipped, defaults to 0.
  • metadata (str) – Optional, ‘true’ or ‘false’ if this call should return the metadata for the feedback.
Status Codes:
  • 200 OK – Yay, you have data!
Response Headers:
 

Recording Recommendation API Endpoints

ListenBrainz uses collaborative filtering to generate recording recommendations, which may be further processed to generate playlists for users. These api endpoints allow to fetch the raw collaborative filtered recording IDs.

GET /1/cf/recommendation/user/(user_name)/recording

Get recommendations sorted on rating and ratings for user user_name.

A sample response from the endpoint may look like:

{
    "payload": {
        "last_updated": 1588494361,
        "type": "<artist_type>",
        "entity": "recording",
        "mbids": [
            {
                "recording_mbid": "526bd613-fddd-4bd6-9137-ab709ac74cab",
                "score": 9.345
            },
            {
                "recording_mbid": "a6081bc1-2a76-4984-b21f-38bc3dcca3a5",
                "score": 6.998
            }
        ],
        "user_name": "unclejohn69",
        "count": 10,
        "total_mbid_count": 30,
        "offset": 10
    }
}

Note

  • This endpoint is experimental and probably will change in the future.
  • <artist_type>: ‘top’ or ‘similar’
Parameters:
  • artist_type (str) –

    Mandatory, artist type in [‘top’, ‘similar’]

    Ex. artist_type = top will fetch recommended recording mbids that belong to top artists listened to by the user.

    artist_type = similar will fetch recommended recording mbids that belong to artists similar to top artists listened to by the user.

  • count (int) – Optional, number of recording mbids to return, Default: DEFAULT_ITEMS_PER_GET Max: MAX_ITEMS_PER_GET
  • offset (int) – Optional, number of mbids to skip from the beginning, for pagination. Ex. An offset of 5 means the 5 mbids will be skipped, defaults to 0
Status Codes:
  • 200 OK – Successful query, you have data!
  • 400 Bad Request – Bad request, check response['error'] for more details
  • 404 Not Found – User not found.
  • 204 No Content – Recommendations for the user haven’t been generated, empty response will be returned

Recording Recommendation Feedback API Endpoints

ListenBrainz uses collaborative filtering to generate recording recommendations, which may be further processed to generate playlists for users. These api endpoints allow to submit and retrieve feedback for raw collaborative filtered recordings.

POST /1/recommendation/feedback/submit

Submit recommendation feedback. A user token (found on https://listenbrainz.org/profile/ ) must be provided in the Authorization header! Each request should contain only one feedback in the payload.

A sample feedback may look like:

{
    "recording_mbid": "d23f4719-9212-49f0-ad08-ddbfbfc50d6f",
    "rating": "love"
}
Request Headers:
 
Status Codes:
Response Headers:
 
POST /1/recommendation/feedback/delete

Delete feedback for a user. A user token (found on https://listenbrainz.org/profile/ ) must be provided in the Authorization header! Each request should contain only one recording mbid in the payload. A sample feedback may look like:

{
    "recording_mbid": "d23f4719-9212-49f0-ad08-ddbfbfc50d6f",
}
Request Headers:
 
Status Codes:
Response Headers:
 
GET /1/recommendation/feedback/user/(user_name)/recordings

Get feedback given by user user_name for the list of recordings supplied.

A sample response may look like:

{
    "feedback": [
        {
            "created": 1604033691,
            "rating": "bad_recommendation",
            "recording_mbid": "9ffabbe4-e078-4906-80a7-3a02b537e251"
        },
        {
            "created": 1604032934,
            "rating": "hate",
            "recording_mbid": "28111d2c-a80d-418f-8b77-6aba58abe3e7"
        }
    ],
    "user_name": "Vansika Pareek"
}

An empty response will be returned if the feedback for given recording MBID doesn’t exist.

Parameters:
  • mbids (str) – comma separated list of recording_mbids for which feedback records are to be fetched.
Status Codes:
Response Headers:
 
GET /1/recommendation/feedback/user/(user_name)

Get feedback given by user user_name.

A sample response may look like:

{
    "count": 1,
    "feedback": [
        {
            "created": "1345679998",
            "recording_mbid": "d23f4719-9212-49f0-ad08-ddbfbfc50d6f",
            "rating": "love"
        },
        "-- more feedback data here ---"
    ],
    "offset": 0,
    "total_count": 1,
    "user_name": "Vansika"
}

If the optional argument rating is not given, this endpoint will return all the feedback submitted by the user. Otherwise filters the feedback to be returned by rating.

Parameters:
  • rating (str) – Optional, refer to db/model/recommendation_feedback.py for allowed rating values.
  • count (int) – Optional, number of feedback items to return, Default: DEFAULT_ITEMS_PER_GET Max: MAX_ITEMS_PER_GET.
  • offset (int) – Optional, number of feedback items to skip from the beginning, for pagination. Ex. An offset of 5 means the top 5 feedback will be skipped, defaults to 0.
Status Codes:
Response Headers:
 

Statistics API Endpoints

ListenBrainz has a statistics infrastructure that collects and computes statistics from the listen data that has been stored in the database. The endpoints in this section offer a way to get this data programmatically.

GET /1/stats/sitewide/listening-activity

Get the listening activity for entire site. The listening activity shows the number of listens the user has submitted over a period of time.

A sample response from the endpoint may look like:

{
    "payload": {
        "from_ts": 1587945600,
        "last_updated": 1592807084,
        "listening_activity": [
            {
                "from_ts": 1587945600,
                "listen_count": 26,
                "time_range": "Monday 27 April 2020",
                "to_ts": 1588031999
            },
            {
                "from_ts": 1588032000,
                "listen_count": 57,
                "time_range": "Tuesday 28 April 2020",
                "to_ts": 1588118399
            },
            {
                "from_ts": 1588118400,
                "listen_count": 33,
                "time_range": "Wednesday 29 April 2020",
                "to_ts": 1588204799
            }
        ],
        "to_ts": 1589155200,
        "range": "week"
    }
}

Note

  • This endpoint is currently in beta
  • The example above shows the data for three days only, however we calculate the statistics for the current time range and the previous time range. For example for weekly statistics the data is calculated for the current as well as the past week.
Parameters:
  • range (str) – Optional, time interval for which statistics should be returned, possible values are ALLOWED_STATISTICS_RANGE, defaults to all_time
Status Codes:
  • 200 OK – Successful query, you have data!
  • 204 No Content – Statistics for the user haven’t been calculated, empty response will be returned
  • 400 Bad Request – Bad request, check response['error'] for more details
Response Headers:
 
GET /1/stats/sitewide/recordings

Get sitewide top recordings.

A sample response from the endpoint may look like:

{
    "payload": {
        "recordings": [
            {
                "artist_mbids": [],
                "artist_name": "Ellie Goulding",
                "listen_count": 25,
                "recording_mbid": "0fe11cd3-0be4-467b-84fa-0bd524d45d74",
                "release_mbid": "",
                "release_name": "Delirium (Deluxe)",
                "track_name": "Love Me Like You Do - From \"Fifty Shades of Grey\""
            },
            {
                "artist_mbids": [],
                "artist_name": "The Fray",
                "listen_count": 23,
                "recording_mbid": "0008ab49-a6ad-40b5-aa90-9d2779265c22",
                "release_mbid": "",
                "release_name": "How to Save a Life",
                "track_name": "How to Save a Life"
            }
        ],
        "offset": 0,
        "count": 2,
        "range": "year",
        "last_updated": 1588494361,
        "from_ts": 1009823400,
        "to_ts": 1590029157
    }
}

Note

  • This endpoint is currently in beta
  • We only calculate the top 1000 all_time recordings
  • artist_mbids, artist_msid, release_name, release_mbid, release_msid, recording_mbid and recording_msid are optional fields and may not be present in all the responses
Parameters:
  • count (int) – Optional, number of artists to return for each time range, Default: DEFAULT_ITEMS_PER_GET Max: MAX_ITEMS_PER_GET
  • offset (int) – Optional, number of artists to skip from the beginning, for pagination. Ex. An offset of 5 means the top 5 artists will be skipped, defaults to 0
  • range (str) – Optional, time interval for which statistics should be returned, possible values are ALLOWED_STATISTICS_RANGE, defaults to all_time
Status Codes:
  • 200 OK – Successful query, you have data!
  • 204 No Content – Statistics haven’t been calculated, empty response will be returned
  • 400 Bad Request – Bad request, check response['error'] for more details
Response Headers:
 
GET /1/stats/sitewide/releases

Get sitewide top releases.

A sample response from the endpoint may look like:

{
    "payload": {
        "releases": [
            {
                "artist_mbids": [],
                "artist_name": "Coldplay",
                "listen_count": 26,
                "release_mbid": "",
                "release_name": "Live in Buenos Aires"
            },
            {
                "artist_mbids": [],
                "artist_name": "Ellie Goulding",
                "listen_count": 25,
                "release_mbid": "",
                "release_name": "Delirium (Deluxe)"
            },
            {
                "artist_mbids": [],
                "artist_name": "The Fray",
                "listen_count": 25,
                "release_mbid": "",
                "release_name": "How to Save a Life"
            },
        ],
        "offset": 0,
        "count": 2,
        "range": "year",
        "last_updated": 1588494361,
        "from_ts": 1009823400,
        "to_ts": 1590029157
    }
}

Note

  • This endpoint is currently in beta
  • artist_mbids, artist_msid, release_mbid and release_msid are optional fields and may not be present in all the responses
Parameters:
  • count (int) – Optional, number of artists to return for each time range, Default: DEFAULT_ITEMS_PER_GET Max: MAX_ITEMS_PER_GET
  • offset (int) – Optional, number of artists to skip from the beginning, for pagination. Ex. An offset of 5 means the top 5 artists will be skipped, defaults to 0
  • range (str) – Optional, time interval for which statistics should be returned, possible values are ALLOWED_STATISTICS_RANGE, defaults to all_time
Status Codes:
  • 200 OK – Successful query, you have data!
  • 204 No Content – Statistics haven’t been calculated, empty response will be returned
  • 400 Bad Request – Bad request, check response['error'] for more details
Response Headers:
 
GET /1/stats/sitewide/artists

Get sitewide top artists.

A sample response from the endpoint may look like:

{
    "payload": {
        "artists": [
            {
                "artist_mbids": [],
                "artist_name": "Kanye West",
                "listen_count": 1305
            },
            {
                "artist_mbids": ["0b30341b-b59d-4979-8130-b66c0e475321"],
                "artist_name": "Lil Nas X",
                "listen_count": 1267
            }
        ],
        "offset": 0,
        "count": 2,
        "range": "year",
        "last_updated": 1588494361,
        "from_ts": 1009823400,
        "to_ts": 1590029157
    }
}

Note

  • This endpoint is currently in beta
  • artist_mbids and artist_msid are optional fields and may not be present in all the entries
  • We only calculate the top 1000 artists for each time period.
Parameters:
  • count (int) – Optional, number of artists to return for each time range, Default: DEFAULT_ITEMS_PER_GET Max: MAX_ITEMS_PER_GET
  • offset (int) – Optional, number of artists to skip from the beginning, for pagination. Ex. An offset of 5 means the top 5 artists will be skipped, defaults to 0
  • range (str) – Optional, time interval for which statistics should be returned, possible values are ALLOWED_STATISTICS_RANGE, defaults to all_time
Status Codes:
  • 200 OK – Successful query, you have data!
  • 204 No Content – Statistics haven’t been calculated, empty response will be returned
  • 400 Bad Request – Bad request, check response['error'] for more details
Response Headers:
 
GET /1/stats/user/(user_name)/listening-activity

Get the listening activity for user user_name. The listening activity shows the number of listens the user has submitted over a period of time.

A sample response from the endpoint may look like:

{
    "payload": {
        "from_ts": 1587945600,
        "last_updated": 1592807084,
        "listening_activity": [
            {
                "from_ts": 1587945600,
                "listen_count": 26,
                "time_range": "Monday 27 April 2020",
                "to_ts": 1588031999
            },
            {
                "from_ts": 1588032000,
                "listen_count": 57,
                "time_range": "Tuesday 28 April 2020",
                "to_ts": 1588118399
            },
            {
                "from_ts": 1588118400,
                "listen_count": 33,
                "time_range": "Wednesday 29 April 2020",
                "to_ts": 1588204799
            },
        "to_ts": 1589155200,
        "user_id": "ishaanshah"
    }
}

Note

  • This endpoint is currently in beta
  • The example above shows the data for three days only, however we calculate the statistics for the current time range and the previous time range. For example for weekly statistics the data is calculated for the current as well as the past week.
  • For all_time listening activity statistics we only return the years which have more than zero listens.
Parameters:
  • range (str) – Optional, time interval for which statistics should be returned, possible values are ALLOWED_STATISTICS_RANGE, defaults to all_time
Status Codes:
  • 200 OK – Successful query, you have data!
  • 204 No Content – Statistics for the user haven’t been calculated, empty response will be returned
  • 400 Bad Request – Bad request, check response['error'] for more details
  • 404 Not Found – User not found
Response Headers:
 
GET /1/stats/user/(user_name)/daily-activity

Get the daily activity for user user_name. The daily activity shows the number of listens submitted by the user for each hour of the day over a period of time. We assume that all listens are in UTC.

A sample response from the endpoint may look like:

{
    "payload": {
        "from_ts": 1587945600,
        "last_updated": 1592807084,
        "daily_activity": {
            "Monday": [
                {
                    "hour": 0
                    "listen_count": 26,
                },
                {
                    "hour": 1
                    "listen_count": 30,
                },
                {
                    "hour": 2
                    "listen_count": 4,
                },
                "..."
            ],
            "Tuesday": ["..."],
            "..."
        },
        "stats_range": "all_time",
        "to_ts": 1589155200,
        "user_id": "ishaanshah"
    }
}

Note

  • This endpoint is currently in beta
Parameters:
  • range (str) – Optional, time interval for which statistics should be returned, possible values are ALLOWED_STATISTICS_RANGE, defaults to all_time
Status Codes:
  • 200 OK – Successful query, you have data!
  • 204 No Content – Statistics for the user haven’t been calculated, empty response will be returned
  • 400 Bad Request – Bad request, check response['error'] for more details
  • 404 Not Found – User not found
Response Headers:
 
GET /1/stats/user/(user_name)/recordings

Get top recordings for user user_name.

A sample response from the endpoint may look like:

{
    "payload": {
        "recordings": [
            {
                "artist_mbids": [],
                "artist_name": "Ellie Goulding",
                "listen_count": 25,
                "recording_mbid": "0fe11cd3-0be4-467b-84fa-0bd524d45d74",
                "release_mbid": "",
                "release_name": "Delirium (Deluxe)",
                "track_name": "Love Me Like You Do - From \"Fifty Shades of Grey\""
            },
            {
                "artist_mbids": [],
                "artist_name": "The Fray",
                "listen_count": 23,
                "recording_mbid": "0008ab49-a6ad-40b5-aa90-9d2779265c22",
                "release_mbid": "",
                "release_name": "How to Save a Life",
                "track_name": "How to Save a Life"
            }
        ],
        "count": 2,
        "total_recording_count": 175,
        "range": "all_time",
        "last_updated": 1588494361,
        "user_id": "John Doe",
        "from_ts": 1009823400,
        "to_ts": 1590029157
    }
}

Note

  • This endpoint is currently in beta
  • We only calculate the top 1000 all_time recordings
  • artist_mbids, artist_msid, release_name, release_mbid, release_msid, recording_mbid and recording_msid are optional fields and may not be present in all the responses
Parameters:
  • count (int) – Optional, number of recordings to return, Default: DEFAULT_ITEMS_PER_GET Max: MAX_ITEMS_PER_GET
  • offset (int) – Optional, number of recordings to skip from the beginning, for pagination. Ex. An offset of 5 means the top 5 recordings will be skipped, defaults to 0
  • range (str) – Optional, time interval for which statistics should be returned, possible values are ALLOWED_STATISTICS_RANGE, defaults to all_time
Status Codes:
  • 200 OK – Successful query, you have data!
  • 204 No Content – Statistics for the user haven’t been calculated, empty response will be returned
  • 400 Bad Request – Bad request, check response['error'] for more details
  • 404 Not Found – User not found
Response Headers:
 
GET /1/stats/user/(user_name)/artist-map

Get the artist map for user user_name. The artist map shows the number of artists the user has listened to from different countries of the world.

A sample response from the endpoint may look like:

{
    "payload": {
        "from_ts": 1587945600,
        "last_updated": 1592807084,
        "artist_map": [
            {
                "country": "USA",
                "artist_count": 34
            },
            {
                "country": "GBR",
                "artist_count": 69
            },
            {
                "country": "IND",
                "artist_count": 32
            }
        ],
        "stats_range": "all_time"
        "to_ts": 1589155200,
        "user_id": "ishaanshah"
    }
}

Note

  • This endpoint is currently in beta
  • We cache the results for this query for a week to improve page load times, if you want to request fresh data you can use the force_recalculate flag.
Parameters:
  • range (str) – Optional, time interval for which statistics should be returned, possible values are ALLOWED_STATISTICS_RANGE, defaults to all_time
  • force_recalculate (bool) – Optional, recalculate the data instead of returning the cached result.
Status Codes:
  • 200 OK – Successful query, you have data!
  • 204 No Content – Statistics for the user haven’t been calculated, empty response will be returned
  • 400 Bad Request – Bad request, check response['error'] for more details
  • 404 Not Found – User not found
Response Headers:
 
GET /1/stats/user/(user_name)/releases

Get top releases for user user_name.

A sample response from the endpoint may look like:

{
    "payload": {
        "releases": [
            {
                "artist_mbids": [],
                "artist_name": "Coldplay",
                "listen_count": 26,
                "release_mbid": "",
                "release_name": "Live in Buenos Aires"
            },
            {
                "artist_mbids": [],
                "artist_name": "Ellie Goulding",
                "listen_count": 25,
                "release_mbid": "",
                "release_name": "Delirium (Deluxe)"
            },
            {
                "artist_mbids": [],
                "artist_name": "The Fray",
                "listen_count": 25,
                "release_mbid": "",
                "release_name": "How to Save a Life"
            },
        ],
        "count": 3,
        "total_release_count": 175,
        "range": "all_time",
        "last_updated": 1588494361,
        "user_id": "John Doe",
        "from_ts": 1009823400,
        "to_ts": 1590029157
    }
}

Note

  • This endpoint is currently in beta
  • artist_mbids, artist_msid, release_mbid and release_msid are optional fields and may not be present in all the responses
Parameters:
  • count (int) – Optional, number of releases to return, Default: DEFAULT_ITEMS_PER_GET Max: MAX_ITEMS_PER_GET
  • offset (int) – Optional, number of releases to skip from the beginning, for pagination. Ex. An offset of 5 means the top 5 releases will be skipped, defaults to 0
  • range (str) – Optional, time interval for which statistics should be returned, possible values are ALLOWED_STATISTICS_RANGE, defaults to all_time
Status Codes:
  • 200 OK – Successful query, you have data!
  • 204 No Content – Statistics for the user haven’t been calculated, empty response will be returned
  • 400 Bad Request – Bad request, check response['error'] for more details
  • 404 Not Found – User not found
Response Headers:
 
GET /1/stats/user/(user_name)/artists

Get top artists for user user_name.

A sample response from the endpoint may look like:

{
    "payload": {
        "artists": [
            {
               "artist_mbids": ["93e6118e-7fa8-49f6-9e02-699a1ebce105"],
               "artist_name": "The Local train",
               "listen_count": 385
            },
            {
               "artist_mbids": ["ae9ed5e2-4caf-4b3d-9cb3-2ad626b91714"],
               "artist_name": "Lenka",
               "listen_count": 333
            },
            {
               "artist_mbids": ["cc197bad-dc9c-440d-a5b5-d52ba2e14234"],
               "artist_name": "Coldplay",
               "listen_count": 321
            }
        ],
        "count": 3,
        "total_artist_count": 175,
        "range": "all_time",
        "last_updated": 1588494361,
        "user_id": "John Doe",
        "from_ts": 1009823400,
        "to_ts": 1590029157
    }
}

Note

  • This endpoint is currently in beta
  • artist_mbids and artist_msid are optional fields and may not be present in all the responses
Parameters:
  • count (int) – Optional, number of artists to return, Default: DEFAULT_ITEMS_PER_GET Max: MAX_ITEMS_PER_GET
  • offset (int) – Optional, number of artists to skip from the beginning, for pagination. Ex. An offset of 5 means the top 5 artists will be skipped, defaults to 0
  • range (str) – Optional, time interval for which statistics should be returned, possible values are ALLOWED_STATISTICS_RANGE, defaults to all_time
Status Codes:
  • 200 OK – Successful query, you have data!
  • 204 No Content – Statistics for the user haven’t been calculated, empty response will be returned
  • 400 Bad Request – Bad request, check response['error'] for more details
  • 404 Not Found – User not found
Response Headers:
 

Status API Endpoints

GET /1/status/get-dump-info

Get information about ListenBrainz data dumps. You need to pass the id parameter in a GET request to get data about that particular dump.

Example response:

{
    "id": 1,
    "timestamp": "20190625-165900"
}
Query Parameters:
 
  • id – Integer specifying the ID of the dump, if not provided, the endpoint returns information about the latest data dump.
Status Codes:
Response Headers:
 

User Timeline API Endpoints

These api endpoints allow to create and fetch timeline events for a user.

POST /1/user/(user_name)/timeline-event/create/notification

Post a message with a link on a user’s timeline. Only approved users are allowed to perform this action.

The request should contain the following data:

{
    "metadata": {
        "message": "<the message to post, required>",
    }
}
Parameters:
  • user_name (str) – The MusicBrainz ID of the user on whose timeline the message is to be posted.
Status Codes:
Response Headers:
 
POST /1/user/(user_name)/timeline-event/create/recording

Make the user recommend a recording to their followers.

The request should post the following data about the recording being recommended:

{
    "metadata": {
        "artist_name": "<The name of the artist, required>",
        "track_name": "<The name of the track, required>",
        "artist_msid": "<The MessyBrainz ID of the artist, required>",
        "recording_msid": "<The MessyBrainz ID of the recording, required>",
        "release_name": "<The name of the release, optional>",
        "recording_mbid": "<The MusicBrainz ID of the recording, optional>"
    }
}
Parameters:
  • user_name (str) – The MusicBrainz ID of the user who is recommending the recording.
Status Codes:
  • 200 OK – Successful query, recording has been recommended!
  • 400 Bad Request – Bad request, check response['error'] for more details.
  • 401 Unauthorized – Unauthorized, you do not have permissions to recommend recordings on the behalf of this user
  • 404 Not Found – User not found
Response Headers:
 
POST /1/user/(user_name)/feed/events/delete

Delete those events from user’s feed that belong to them. Supports deletion of recommendation and notification. Along with the authorization token, post the event type and event id. For example:

{
    "event_type": "recording_recommendation",
    "id": "<integer id of the event>"
}
{
    "event_type": "notification",
    "id": "<integer id of the event>"
}
Parameters:
  • user_name (str) – The MusicBrainz ID of the user from whose timeline events are being deleted
Status Codes:
Response Headers:
 
GET /1/user/(user_name)/feed/events

Get feed events for a user’s timeline.

Parameters:
  • user_name (str) – The MusicBrainz ID of the user whose timeline is being requested.
  • max_ts – If you specify a max_ts timestamp, events with timestamps less than the value will be returned
  • min_ts – If you specify a min_ts timestamp, events with timestamps greater than the value will be returned
  • count (int) – Optional, number of events to return. Default: DEFAULT_ITEMS_PER_GET . Max: MAX_ITEMS_PER_GET
Status Codes:
  • 200 OK – Successful query, you have feed events!
  • 400 Bad Request – Bad request, check response['error'] for more details.
  • 401 Unauthorized – Unauthorized, you do not have permission to view this user’s feed.
  • 404 Not Found – User not found
Response Headers:
 

Social API Endpoints

These apis allow to interact with social features of ListenBrainz.

GET /1/user/(user_name)/followers

Fetch the list of followers of the user user_name. Returns a JSON with an array of user names like these:

{
    "followers": ["rob", "mr_monkey", "..."],
    "user": "shivam-kapila"
}
Status Codes:
GET /1/user/(user_name)/following

Fetch the list of users followed by the user user_name. Returns a JSON with an array of user names like these:

{
    "followers": ["rob", "mr_monkey", "..."],
    "user": "shivam-kapila"
}
Status Codes:
POST /1/user/(user_name)/unfollow

Unfollow the user user_name. A user token (found on https://listenbrainz.org/profile/ ) must be provided in the Authorization header!

Request Headers:
 
Status Codes:
  • 200 OK – Successfully unfollowed the user user_name.
  • 401 Unauthorized – invalid authorization. See error message for details.
Response Headers:
 
POST /1/user/(user_name)/follow

Follow the user user_name. A user token (found on https://listenbrainz.org/profile/ ) must be provided in the Authorization header!

Request Headers:
 
Status Codes:
  • 200 OK – Successfully followed the user user_name.
  • 400 Bad Request
    • Already following the user user_name.
    • Trying to follow yourself.
  • 401 Unauthorized – invalid authorization. See error message for details.
Response Headers:
 

Pinned Recording API Endpoints

These API endpoints allow submitting, deleting, and retrieving ListenBrainz pinned recordings for users.

POST /1/pin/unpin

Unpins the currently active pinned recording for the user. A user token (found on https://listenbrainz.org/profile/) must be provided in the Authorization header!

Request Headers:
 
Status Codes:
  • 200 OK – recording unpinned.
  • 401 Unauthorized – invalid authorization. See error message for details.
  • 404 Not Found – could not find the active recording to unpin for the user. See error message for details.
Response Headers:
 
POST /1/pin

Pin a recording for user. A user token (found on https://listenbrainz.org/profile/) must be provided in the Authorization header! Each request should contain only one pinned recording item in the payload.

The format of the JSON to be POSTed to this endpoint should look like the following:

{
    "recording_msid": "40ef0ae1-5626-43eb-838f-1b34187519bf",
    "recording_mbid": "<this field is optional>",
    "blurb_content": "Wow..",
    "pinned_until": 1824001816
}
Request Headers:
 
Status Codes:
Response Headers:
 
POST /1/pin/delete/(row_id)

Deletes the pinned recording with given row_id from the server. A user token (found on https://listenbrainz.org/profile/) must be provided in the Authorization header!

Request Headers:
 
Parameters:
  • row_id (int) – the row_id of the pinned recording that should be deleted.
Status Codes:
Response Headers:
 
GET /1/(user_name)/pins/following

Get a list containing the active pinned recordings for all users in a user’s user_name following list. The returned pinned recordings are sorted in descending order of the time they were pinned. The JSON returned by the API will look like the following:

{
    "count": 1,
    "offset": 0,
    "pinned_recordings": [
        {
        "blurb_content": "Spectacular recording!",
        "created": 1624000841,
        "row_id": 1,
        "pinned_until": 1624605641,
        "recording_mbid": null,
        "recording_msid": "40ef0ae1-5626-43eb-838f-1b34187519bf",
        "track_metadata": {
                "artist_msid": "8c7b4641-e363-4598-ae70-7709840fb934",
                "artist_name": "Rick Astley",
                "track_name": "Never Gonna Give You Up"
        },
        "user_name": "-- the MusicBrainz ID of the user who pinned this recording --"
        },
        "-- more pinned recordings from different users here ---"
    ],
    "user_name": "-- the MusicBrainz ID of the original user --"
}
Parameters:
  • user_name (str) – the MusicBrainz ID of the user whose followed user’s pinned recordings are being requested.
  • count (int) – Optional, number of pinned recording items to return, Default: DEFAULT_ITEMS_PER_GET Max: MAX_ITEMS_PER_GET
  • offset (int) – Optional, number of pinned recording items to skip from the beginning, for pagination. Ex. An offset of 5 means the most recent pinned recordings from the first 5 users will be skipped, defaults to 0
Status Codes:
Response Headers:
 
GET /1/(user_name)/pins

Get a list of all recordings ever pinned by a user with given user_name in descending order of the time they were originally pinned. The JSON returned by the API will look like the following:

{
    "count": 10,
    "offset": 0,
    "pinned_recordings": [
        {
            "blurb_content": "Awesome recording!",
            "created": 1623997168,
            "row_id": 10,
            "pinned_until": 1623997485,
            "recording_mbid": null,
            "recording_msid": "fd7d9162-a284-4a10-906c-faae4f1e166b"
            "track_metadata": {
                "artist_msid": "8c7b4641-e363-4598-ae70-7709840fb934",
                "artist_name": "Rick Astley",
                "track_name": "Never Gonna Give You Up"
                }
        },
        "-- more pinned recording items here ---"
    ],
    "total_count": 10,
    "user_name": "-- the MusicBrainz ID of the user --"
}
Parameters:
  • user_name (str) – the MusicBrainz ID of the user whose pin track history requested.
  • count (int) – Optional, number of pinned recording items to return, Default: DEFAULT_ITEMS_PER_GET Max: MAX_ITEMS_PER_GET
  • offset (int) – Optional, number of pinned recording items to skip from the beginning, for pagination. Ex. An offset of 5 means the most recent 5 pinned recordings from the user will be skipped, defaults to 0
Status Codes:
Response Headers:
 

Color API Endpoints

These API endpoints allow fetching releases with recordings and cover art details for a given color.

GET /1/color/(color)

Fetch a list of releases that have cover art that has a predominant color that is close to the given color.

{
    "payload": {
        "releases" : [
            {
              "artist_name": "Letherette",
              "color": [ 250, 90, 192 ],
              "dist": 109.973,
              "release_mbid": "00a109da-400c-4350-9751-6e6f25e89073",
              "caa_id": 34897349734,
              "release_name": "EP5",
              "recordings": "< array of listen formatted metadata >",
              },
            ". . ."
        ]
    }
}
Status Codes:
Response Headers:
 

Rate limiting

The ListenBrainz API is rate limited via the use of rate limiting headers that are sent as part of the HTTP response headers. Each call will include the following headers:

  • X-RateLimit-Limit: Number of requests allowed in given time window
  • X-RateLimit-Remaining: Number of requests remaining in current time window
  • X-RateLimit-Reset-In: Number of seconds when current time window expires (recommended: this header is resilient against clients with incorrect clocks)
  • X-RateLimit-Reset: UNIX epoch number of seconds (without timezone) when current time window expires [#]

Rate limiting is automatic and the client must use these headers to determine the rate to make API calls. If the client exceeds the number of requests allowed, the server will respond with error code 429: Too Many Requests. Requests that provide the Authorization header with a valid user token may receive higher rate limits than those without valid user tokens.

[1]Provided for compatibility with other APIs, but we still recommend using X-RateLimit-Reset-In wherever possible

Timestamps

All timestamps used in ListenBrainz are UNIX epoch timestamps in UTC. When submitting timestamps to us, please ensure that you have no timezone adjustments on your timestamps.

Constants

Constants that are relevant to using the API:

listenbrainz.webserver.views.api_tools.MAX_LISTEN_SIZE = 10240

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.__int__(). For floating point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by ‘+’ or ‘-‘ and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal. >>> int(‘0b100’, base=0) 4

listenbrainz.webserver.views.api_tools.MAX_ITEMS_PER_GET = 100

The maximum number of listens returned in a single GET request.

listenbrainz.webserver.views.api_tools.DEFAULT_ITEMS_PER_GET = 25

The default number of listens returned in a single GET request.

listenbrainz.webserver.views.api_tools.MAX_TAGS_PER_LISTEN = 50

The maximum number of tags per listen.

listenbrainz.webserver.views.api_tools.MAX_TAG_SIZE = 64

The maximum length of a tag

listenbrainz.webserver.views.api_tools.LISTEN_MINIMUM_TS = 1033430400

The minimum acceptable value for listened_at field

data.model.common_stat.ALLOWED_STATISTICS_RANGE = ['week', 'month', 'quarter', 'half_yearly', 'year', 'all_time', 'this_week', 'this_month', 'this_year']

list of allowed value for range param accepted by various statistics endpoints