Rate Your Music APIrateyourmusic.com ↗
Access RateYourMusic album ratings, artist discographies, genre hierarchies, and top/bottom charts via 6 structured endpoints.
What is the Rate Your Music API?
The Rate Your Music API gives developers structured access to RYM's music catalog across 6 endpoints, covering release details, artist discographies, genre hierarchies, and paginated chart data. The get_charts endpoint lets you pull ranked albums, EPs, singles, and tracks filtered by chart type and year, while get_release_details returns tracklists, descriptors, average ratings, and genre tags for any release.
curl -X GET 'https://api.parse.bot/scraper/4543201b-0c81-4415-b1a4-83478db54412/get_charts?page=1&year=all-time&chart_type=top&media_type=album' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace rateyourmusic-com-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""
Rate Your Music API Client
Parse bot integration for RateYourMusic data extraction.
Get your API key from: https://parse.bot/settings
"""
import os
import requests
from typing import Optional, Any, Dict, List
class ParseClient:
"""Client for Rate Your Music Parse API."""
def __init__(self, api_key: Optional[str] = None):
"""
Initialize the Parse API client.
Args:
api_key: API key for Parse bot. If not provided, reads from PARSE_API_KEY env var.
"""
self.base_url = "https://api.parse.bot"
self.scraper_id = "4543201b-0c81-4415-b1a4-83478db54412"
self.api_key = api_key or os.getenv("PARSE_API_KEY")
if not self.api_key:
raise ValueError("API key must be provided or set in PARSE_API_KEY environment variable")
def _call(self, endpoint: str, method: str = "POST", **params) -> Dict[str, Any]:
"""
Make a request to the Parse API.
Args:
endpoint: API endpoint name
method: HTTP method (GET or POST)
**params: Query/body parameters
Returns:
Response JSON as dictionary
"""
url = f"{self.base_url}/scraper/{self.scraper_id}/{endpoint}"
headers = {
"X-API-Key": self.api_key,
"Content-Type": "application/json"
}
if method.upper() == "GET":
response = requests.get(url, headers=headers, params=params)
else:
response = requests.post(url, headers=headers, json=params)
response.raise_for_status()
return response.json()
def get_charts(
self,
media_type: str = "album",
chart_type: str = "top",
year: str = "all-time",
page: int = 1
) -> Dict[str, Any]:
"""
Extract charts data for albums or tracks.
Args:
media_type: Type of media (album, track, ep, single, etc.)
chart_type: Type of chart (top, bottom, etc.)
year: Year or year range (e.g. 2024, 2020-2024, all-time)
page: Page number for pagination
Returns:
Dictionary with 'total' count and 'items' array of chart entries
"""
return self._call(
"get_charts",
method="GET",
media_type=media_type,
chart_type=chart_type,
year=year,
page=page
)
def get_release_details(self, url: str) -> Dict[str, Any]:
"""
Extract detailed album/release information including tracklisting.
Args:
url: Release URL (e.g. /release/album/kendrick-lamar/to-pimp-a-butterfly/)
Returns:
Dictionary with artist, title, genres, tracklist, rating info
"""
return self._call("get_release_details", method="GET", url=url)
def get_artist_details(self, url: str) -> Dict[str, Any]:
"""
Extract detailed artist information and discography.
Args:
url: Artist URL (e.g. /artist/kendrick-lamar)
Returns:
Dictionary with artist name, genres, and discography array
"""
return self._call("get_artist_details", method="GET", url=url)
def get_genres(self) -> Dict[str, Any]:
"""
List all music genres available on the site.
Returns:
Dictionary with 'genres' array containing name and url for each genre
"""
return self._call("get_genres", method="GET")
def get_genre_details(self, url: str) -> Dict[str, Any]:
"""
Extract detailed genre information including description and parents.
Args:
url: Genre URL (e.g. /genre/conscious-hip-hop/)
Returns:
Dictionary with genre name, description, and parent genres
"""
return self._call("get_genre_details", method="GET", url=url)
def search(self, query: str, search_type: str = "all") -> Dict[str, Any]:
"""
Search for artists, releases, or genres.
Args:
query: Search keyword
search_type: Search type (all, a for artist, l for album, g for genre)
Returns:
Dictionary with 'results' array of matching items
"""
return self._call("search", method="GET", query=query, search_type=search_type)
def main():
"""Practical workflow: discover top-rated albums and explore their details."""
client = ParseClient()
print("=" * 70)
print("Rate Your Music Discovery Tool")
print("=" * 70)
# Step 1: Get top albums of all time
print("\n[1] Fetching top-rated albums of all time...")
try:
charts = client.get_charts(media_type="album", chart_type="top", year="all-time", page=1)
except Exception as e:
print(f"Error fetching charts: {e}")
return
items = charts.get("data", {}).get("items", [])
if not items:
print("No albums found in charts")
return
print(f"Retrieved {len(items)} top albums")
# Step 2: Explore details for top 3 albums
top_albums = items[:3]
print("\n[2] Fetching detailed information for top 3 albums...")
print("-" * 70)
for idx, album in enumerate(top_albums, 1):
album_rank = album.get("rank")
album_title = album.get("release_name")
artist_name = album.get("artist")
album_url = album.get("release_url")
rating = album.get("rating")
rating_count = album.get("ratings_count")
review_count = album.get("reviews_count")
genres = album.get("primary_genres", [])
print(f"\n[Album #{idx}] #{album_rank} - {album_title}")
print(f" Artist: {artist_name}")
print(f" Rating: {rating} ⭐ ({rating_count} ratings, {review_count} reviews)")
print(f" Genres: {', '.join(genres)}")
# Get detailed tracklist
if album_url:
try:
release_data = client.get_release_details(url=album_url)
release_info = release_data.get("data", {})
tracklist = release_info.get("tracklist", [])
if tracklist:
print(f" Tracklist ({len(tracklist)} tracks):")
for track in tracklist[:5]:
track_num = track.get("num")
track_name = track.get("name")
duration = track.get("duration")
has_lyrics = "🎤" if track.get("has_lyrics") else ""
print(f" {track_num}. {track_name} ({duration}) {has_lyrics}")
if len(tracklist) > 5:
print(f" ... and {len(tracklist) - 5} more tracks")
except Exception as e:
print(f" (Could not fetch release details: {str(e)[:50]})")
# Step 3: Search for a specific artist and explore their discography
print("\n" + "-" * 70)
print("\n[3] Searching for artist 'Radiohead'...")
try:
search_results = client.search(query="Radiohead", search_type="a")
results = search_results.get("data", {}).get("results", [])
if results:
artist_result = results[0]
artist_name = artist_result.get("name")
artist_url = artist_result.get("url")
print(f"Found: {artist_name}")
# Get artist details and discography
print("\n[4] Fetching artist details and discography...")
artist_data = client.get_artist_details(url=artist_url)
artist_info = artist_data.get("data", {})
discography = artist_info.get("discography", [])
artist_genres = artist_info.get("genres", [])
print(f" Genres: {', '.join(artist_genres)}")
print(f" Total releases: {len(discography)}")
# Sort by rating and show top 5
top_releases = sorted(
discography,
key=lambda x: float(x.get("rating", "0")),
reverse=True
)[:5]
print("\n Top 5 highest-rated releases:")
for idx, release in enumerate(top_releases, 1):
title = release.get("title")
year = release.get("year", "N/A")
rating = release.get("rating")
ratings_count = release.get("ratings_count")
print(f" {idx}. {title} ({year}) - {rating} ⭐ ({ratings_count} ratings)")
else:
print("No artists found matching the search")
except Exception as e:
print(f"Error during artist search: {e}")
# Step 4: Explore genres
print("\n" + "-" * 70)
print("\n[5] Exploring available genres...")
try:
genres_data = client.get_genres()
genres_list = genres_data.get("data", {}).get("genres", [])
if genres_list:
print(f"Total genres available: {len(genres_list)}")
print("Sample genres:")
for genre in genres_list[:5]:
genre_name = genre.get("name")
genre_url = genre.get("url")
print(f" • {genre_name}")
# Get genre details
try:
genre_details = client.get_genre_details(url=genre_url)
genre_info = genre_details.get("data", {})
description = genre_info.get("description", "")
parents = genre_info.get("parents", [])
if description:
desc_preview = description[:80] + "..." if len(description) > 80 else description
print(f" Description: {desc_preview}")
if parents:
print(f" Parent genres: {', '.join(parents)}")
except Exception as e:
pass
except Exception as e:
print(f"Error fetching genres: {e}")
print("\n" + "=" * 70)
print("Discovery complete!")
print("=" * 70)
if __name__ == "__main__":
main()Extract charts data for albums or tracks. Returns paginated results with 40 items per page. Supports filtering by media type, chart type, year, and pagination.
| Param | Type | Description |
|---|---|---|
| page | integer | Page number for pagination (1-indexed). |
| year | string | Year or year range (e.g. 2024, 2020-2024, all-time). |
| chart_type | string | Type of chart. Accepted values: top, bottom. |
| media_type | string | Type of media. Accepted values: album, track, ep, single. |
{
"type": "object",
"fields": {
"items": "array of chart entries with rank, release_name, artist, date, release_type, genres, rating info",
"total": "integer count of items returned on this page"
},
"sample": {
"data": {
"items": [
{
"date": "15 March 2015",
"rank": 1,
"artist": "Kendrick Lamar",
"rating": "4.38",
"artist_url": "https://rateyourmusic.com/artist/kendrick-lamar",
"release_url": "https://rateyourmusic.com/release/album/kendrick-lamar/to-pimp-a-butterfly/",
"release_name": "To Pimp a Butterfly",
"release_type": "Album",
"ratings_count": "105k",
"reviews_count": "1k",
"primary_genres": [
"Conscious Hip Hop",
"Jazz Rap"
],
"secondary_genres": [
"Political Hip Hop",
"Neo-Soul"
]
}
],
"total": 40
},
"status": "success"
}
}About the Rate Your Music API
Release and Artist Data
The get_release_details endpoint accepts a release URL path and returns the title, artist, genres array, descriptors array, tracklist, average rating, and rating count. The get_artist_details endpoint takes an artist URL path and returns the artist's name, associated genres, and a full discography array — each entry includes the release title, URL, year, average rating, and ratings count.
Charts
The get_charts endpoint returns paginated chart results — 40 items per page — filterable by media_type (album, track, EP, or single), chart_type (top or bottom), and year (a single year like 2024, a range like 2020-2024, or all-time). Each chart entry includes rank, release name, artist, release date, release type, genres, and rating information. Use the page parameter to step through results.
Genre Hierarchy
The get_genres endpoint returns a flat list of all genres available on RYM, each with a name and URL. The get_genre_details endpoint accepts a genre URL path and returns the genre name, its description text, and an array of parent genre names, exposing the full hierarchical relationship between genres.
Search
The search endpoint accepts a query string and an optional search_type filter (all, a for artists, l for releases, or g for genres). Results return an array of objects, each with a name, URL, and type field (artist, release, genre, or other), making it straightforward to feed results into the detail endpoints.
The Rate Your Music API is a managed, monitored endpoint for rateyourmusic.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when rateyourmusic.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official rateyourmusic.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Build a music recommendation tool that surfaces top-rated albums by genre using
get_chartsfiltered bymedia_typeandyear. - Aggregate an artist's full discography with ratings and release years via
get_artist_details. - Construct a genre taxonomy or knowledge graph using parent-child relationships from
get_genre_details. - Track chart position trends for a specific release type (EP, single) across multiple years.
- Display tracklists and descriptors for releases in a music cataloging application using
get_release_details. - Search RYM's catalog by keyword and type to resolve artist or album names to canonical URLs.
- Analyze bottom-rated releases in a given year using the
chart_type=bottomfilter onget_charts.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does Rate Your Music have an official developer API?+
What does `get_charts` return and how do I filter it?+
media_type (album, track, ep, single), chart_type (top or bottom), and year (e.g. 2024, 2020-2024, or all-time). Use the page parameter to paginate through results.Does the API expose user review text or individual user ratings?+
Are lists (user-curated or official RYM lists) accessible through this API?+
What is a limitation to be aware of when using genre data?+
get_genre_details returns parent genre names as strings, not URLs or IDs, so traversing the full hierarchy requires first resolving parent names to URLs using the get_genres endpoint. Also, genre descriptions may be absent for less-documented genres.