Users
A user’s ratings
GET/v1/users/{userId}/ratings
No API keyRate-limitedPaginated
Their public ratings, most recently changed first. A rating is a whole number from 0 to 100.
Parameters#
Path parameters#
| Name | Type | Description |
|---|---|---|
| userIdrequired | string | A Rankd user id: usr_ then 26 characters. Get one from Look up a user by username.Pattern: ^usr_[0-9A-Z]{26}$ · Example: usr_01KY0JGXMWTT8H9WFN9RTM5JP9 |
Query parameters#
| Name | Type | Description |
|---|---|---|
| limit | integer default 30 | How many items to return. Default 30, at most 100. Larger values are capped at 100; anything that is not a positive whole number gives the default. |
| cursor | string | The meta.nextCursor of the previous page. Leave it out for the first page. Cursors are opaque: pass them back unchanged. |
Try it#
Sends a real request to the production API through this site. No credentials are used, so you see exactly what anyone would.
Response
Request#
curl "https://api.rankdmusic.app/v1/users/usr_01KY0JGXMWTT8H9WFN9RTM5JP9/ratings"const response = await fetch('https://api.rankdmusic.app/v1/users/usr_01KY0JGXMWTT8H9WFN9RTM5JP9/ratings');
const body = await response.json();
if (!response.ok) {
const code = typeof body.error === 'string' ? body.error : body.error.code;
throw new Error(`Rankd API ${response.status}: ${code}`);
}
const { data, meta } = body;
// meta.nextCursor: pass it as ?cursor= for the next pageimport Foundation
let url = URL(string: "https://api.rankdmusic.app/v1/users/usr_01KY0JGXMWTT8H9WFN9RTM5JP9/ratings")!
let (data, response) = try await URLSession.shared.data(from: url)
guard let http = response as? HTTPURLResponse, http.statusCode == 200 else {
throw URLError(.badServerResponse)
}
let body = try JSONSerialization.jsonObject(with: data) as? [String: Any]
let result = body?["data"]
let nextCursor = (body?["meta"] as? [String: Any])?["nextCursor"] as? Stringimport requests
response = requests.get("https://api.rankdmusic.app/v1/users/usr_01KY0JGXMWTT8H9WFN9RTM5JP9/ratings", timeout=10)
body = response.json()
if not response.ok:
error = body["error"]
raise RuntimeError(error if isinstance(error, str) else error["code"])
data = body["data"]
next_cursor = body["meta"].get("nextCursor")Response#
A successful response is { "data": …, "meta": … }. data is an array of Rating objects, and meta is a PageMeta.
| Field | Type | Description |
|---|---|---|
| idalways | string | The rating’s id. |
| musicalways | MusicRef | |
| valuealways | integer | The rating, 0–100. Rankd’s apps show it as stars (value ÷ 20) or as a score out of 100. |
| visibility | string or null | public, or null for ratings made before Rankd had visibility settings (those are public too).One of: public |
| createdAt | string (date-time) or null | When it was made. |
| createdAtPrecision | string | approximate for ratings imported without an exact time.One of: exact, approximate |
| updatedAt | string (date-time) or null | When it last changed. |
meta (PageMeta)#
| Field | Type | Description |
|---|---|---|
| apiVersionalways | integer | The API version that answered. |
| migrationPhase | integer | Internal to Rankd. Ignore it. |
| sourceOfTruth | string | Internal to Rankd. Ignore it. |
| nextCursor | string or null | Pass this as cursor to get the next page. null or missing on the last page. |
Responses#
200A page of ratings.
Captured from production: GET /v1/users/usr_01KY0JGXMWTT8H9WFN9RTM5JP9/ratings?limit=2
200 response
{
"data": [
{
"id": "rat_01M3QSX2M2ESSG165BGJWYM5ZS",
"music": {
"provider": "apple_music",
"type": "song",
"id": "697195462",
"title": "One More Time",
"artistName": "Daft Punk",
"artworkUrl": "https://is1-ssl.mzstatic.com/image/thumb/Music221/v4/fd/4a/77/fd4a77db-0ebc-d043-41a2-f32fa1bb0fb4/dj.qrikkdwj.jpg/600x600bb.jpg",
"albumId": "697194953",
"albumTitle": "Discovery"
},
"value": 80,
"visibility": "public",
"createdAt": "2026-09-30T00:02:19.906Z",
"createdAtPrecision": "exact",
"updatedAt": "2026-09-30T00:02:19.906Z"
},
{
"id": "rat_01M3EZRBAW621QVN73BHKENP8B",
"music": {
"provider": "apple_music",
"type": "song",
"id": "6814997428",
"title": "Pink Clouding",
"artistName": "Taylor Swift",
"artworkUrl": "https://is1-ssl.mzstatic.com/image/thumb/Music221/v4/a0/dd/fd/a0ddfd72-ee9e-f046-6466-a5dbefc696fa/26UM1IM21436.rgb.jpg/600x600bb.jpg",
"albumId": "6814997249",
"albumTitle": "The Life of a Showgirl: The Encore"
},
"value": 100,
"visibility": null,
"createdAt": "2026-09-26T13:51:26.556Z",
"createdAtPrecision": "exact",
"updatedAt": "2026-09-29T23:40:53.152Z"
}
],
"meta": {
"apiVersion": 1,
"migrationPhase": 3,
"sourceOfTruth": "per_account",
"nextCursor": "MTc5MDcyNTI1MzE1MnxyYXRfMDFNM0VaUkJBVzYyMVFWTjczQkhLRU5QOEI"
}
}404No such user, or they are not discoverable.
Captured from production: GET /v1/users/by-username/no_such_person_zz
404 response
{
"error": {
"code": "not_found",
"message": "User not found."
}
}429Too many requests this minute. Wait Retry-After seconds, then try again.
Headers: Retry-After Seconds to wait. Always 60.
429 response
{
"error": "rate limited"
}