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 token to check as the token argument (example: /validate-token?token=token-to-check)

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

  • If the given token is valid:

    {
        "code": 200,
        "message": "Token valid.",
        "valid": True,
        "user": "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/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!

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)/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
  • 200 OK – Yay, you have listen counts!

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
  • 200 OK – Yay, you have data!

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

  • time_range – This parameter determines the time range for the listen search. Each increment of the time_range corresponds to a range of 5 days and the default time_range of 3 means that 15 days will be searched. Default: DEFAULT_TIME_RANGE . Max: MAX_TIME_RANGE

Status Codes
  • 200 OK – Yay, you have data!

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
}
Parameters
  • user_name – 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.

Statistics API Endpoints

ListenBrainz now 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/artists

Get sitewide top artists.

A sample response from the endpoint may look like:

{
    "payload": {
        "time_ranges": [
            {
                "time_range": "April 2020",
                "artists": [
                    {
                        "artist_mbids": ["f4fdbb4c-e4b7-47a0-b83b-d91bbfcfa387"],
                        "artist_msid": "b4ae3356-b8a7-471a-a23a-e471a69ad454",
                        "artist_name": "Ariana Grande",
                        "listen_count": 519
                    },
                    {
                        "artist_mbids": ["f4abc0b5-3f7a-4eff-8f78-ac078dbce533"],
                        "artist_msid": "f9ee09fb-5ab4-46a2-9088-3eac0eed4920",
                        "artist_name": "Billie Eilish",
                        "listen_count": 447
                    }
                ],
                "from_ts": 1585699200,
                "to_ts": 1588291199,
            },
            {
                "time_range": "May 2020",
                "artists": [
                    {
                        "artist_mbids": [],
                        "artist_msid": "2b0646af-f3f0-4a5b-b629-6c31301c1c29",
                        "artist_name": "The Weeknd",
                        "listen_count": 621
                    },
                    {
                        "artist_mbids": [],
                        "artist_msid": "9720fd77-fe48-41ba-a7a2-b4795718dd97",
                        "artist_name": "Drake",
                        "listen_count": 554
                    }
                ],
                "from_ts": 1588291200,
                "to_ts": 1590969599
            }
        ],
        "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

  • The example above shows the data for two days only, however we calculate the statistics for the current time range and the previous time range. For example for yearly statistics the data is calculated for the months in current as well as the past year.

  • 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 collected, possible values are week, month, year, all_time, 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 week, month, year, all_time, 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 week, month, year, all_time, 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_msid": "7addbcac-ae39-4b4c-a956-53da336d68e8",
                "artist_name": "Ellie Goulding",
                "listen_count": 25,
                "recording_mbid": "0fe11cd3-0be4-467b-84fa-0bd524d45d74",
                "recording_msid": "c6b65a7e-7284-433e-ac5d-e3ff0aa4738a",
                "release_mbid": "",
                "release_msid": "de97ca87-36c4-4995-a5c9-540e35944352",
                "release_name": "Delirium (Deluxe)",
                "track_name": "Love Me Like You Do - From "Fifty Shades of Grey""
            },
            {
                "artist_mbids": [],
                "artist_msid": "3b155259-b29e-4515-aa62-cb0b917f4cfd",
                "artist_name": "The Fray",
                "listen_count": 23,
                "recording_mbid": "0008ab49-a6ad-40b5-aa90-9d2779265c22",
                "recording_msid": "4b5bf07c-782f-4324-9242-bf56e4ba1e57",
                "release_mbid": "",
                "release_msid": "2b2a93c3-a0bd-4f46-8507-baf5ad291966",
                "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 collected, possible values are week, month, year, all_time, 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 (bool) – Optional, time interval for which statistics should be returned, possible values are week, month, year, all_time, defaults to all_time

  • force_recalculate – 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_msid": "6599e41e-390c-4855-a2ac-68ee798538b4",
                "artist_name": "Coldplay",
                "listen_count": 26,
                "release_mbid": "",
                "release_msid": "d59730cf-f0e3-441e-a7a7-8e0f589632a5",
                "release_name": "Live in Buenos Aires"
            },
            {
                "artist_mbids": [],
                "artist_msid": "7addbcac-ae39-4b4c-a956-53da336d68e8",
                "artist_name": "Ellie Goulding",
                "listen_count": 25,
                "release_mbid": "",
                "release_msid": "de97ca87-36c4-4995-a5c9-540e35944352",
                "release_name": "Delirium (Deluxe)"
            },
            {
                "artist_mbids": [],
                "artist_msid": "3b155259-b29e-4515-aa62-cb0b917f4cfd",
                "artist_name": "The Fray",
                "listen_count": 25,
                "release_mbid": "",
                "release_msid": "2b2a93c3-a0bd-4f46-8507-baf5ad291966",
                "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 collected, possible values are week, month, year, all_time, 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_msid": "d340853d-7408-4a0d-89c2-6ff13e568815",
               "artist_name": "The Local train",
               "listen_count": 385
            },
            {
               "artist_mbids": ["ae9ed5e2-4caf-4b3d-9cb3-2ad626b91714"],
               "artist_msid": "ba64b195-01dd-4613-9534-bb87dc44cffb",
               "artist_name": "Lenka",
               "listen_count": 333
            },
            {
               "artist_mbids": ["cc197bad-dc9c-440d-a5b5-d52ba2e14234"],
               "artist_msid": "6599e41e-390c-4855-a2ac-68ee798538b4",
               "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 collected, possible values are week, month, year, all_time, 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

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

Maximum overall listen size in bytes, to prevent egregious spamming.

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