Overview
Every route lives under https://api.musicapi.com/trpc/. Each endpoint is a tRPC procedure reached over plain HTTP, so you need no client library: a GET reads, a POST writes, and both speak JSON. The API is included with the Pro plan.
- Charts — the daily leaderboards: who is gaining, who is on top, which playlists are growing.
- Details — one artist, track or playlist at a time, with its playlist history and visibility score.
- Your data — what the authenticated user follows, plus their daily and weekly digest reports.
- Insights — statistical signals on top of the daily data: acceleration and anomalies.
Prefer an AI client to a script? The same data is exposed over an MCP server that connects with OAuth instead of a personal access token.
https://api.musicapi.com. Tokens are minted in the Music24 app, which runs on its own host — nothing on this page lives there, so that host is not one you need to call. Your m24_ token works here from the moment it is created.curl 'https://api.musicapi.com/trpc/artists.topGaining?input=%7B%22json%22%3A%7B%22limit%22%3A5%7D%7D' \ -H 'Authorization: Token m24_xxxxxxxxxxxxxxxxxxxxxxxx'
{
"result": {
"data": {
"json": {
"artists": [
{
"artistMaid": "2ab91f6e-...",
"mainArtistName": "Role Model",
"imageUrl": "https://.../role-model.jpg",
"addedToPlaylists": { "current": 0.42, "previous": 0.31 },
"removedFromPlaylists": { "current": 0.02, "previous": 0.05 }
}
],
"pagination": { "limit": 5, "offset": 0 }
}
}
}
}Authentication
Send a personal access token in an Authorization header. There is no other mechanism — no query-string keys, no cookies, no basic auth. Both schemes are accepted: Token and Bearer behave identically.
Create a token in Settings → API access in the Music24 app. The plaintext is shown exactly once, at creation — Music24 stores only its hash — so write it down before you close the dialog. You can hold five active tokens; revoke one to make room for another.
Authorization: Token m24_xxxxxxxxxxxxxxxxxxxxxxxx
{
"error": {
"message": "UNAUTHORIZED",
"code": -32001,
"data": {
"code": "UNAUTHORIZED",
"httpStatus": 401,
"path": "artists.topGaining"
}
}
}Requests & responses
A query (any read) is a GET. Its arguments travel in an input query parameter as URL-encoded JSON, wrapped in { "json": … }:
GET /trpc/artists.topGaining?input=%7B%22json%22%3A%7B%22limit%22%3A5%7D%7D
A mutation (follow and unfollow) is a POST with the same { "json": … } shape as the request body and Content-Type: application/json.
Conventions worth knowing
- Every success is wrapped identically:
{ "result": { "data": { "json": … } } }. Read through tojsonand ignore the envelope. - List endpoints page with
limitandoffset, and tell you where you are in apaginationorhasMorefield. - Ids are opaque strings —
maidfor artists and tracks,playlistIdfor playlists. Store them as given. - Dates are ISO
YYYY-MM-DDin UTC, and adateargument always means the day the data is for, not the day you asked.
curl -X POST 'https://api.musicapi.com/trpc/artists.follow' \ -H 'Authorization: Token m24_xxxxxxxxxxxxxxxxxxxxxxxx' \ -H 'Content-Type: application/json' \ -d '{"json":{"artistId":"2ab91f6e-..."}}'
{
"result": {
"data": {
"json": { "success": true, "message": "Successfully followed artist" }
}
}
}{"json":{"limit":5}}Errors
A failed call returns a non-2xx status and a single, consistent body. Branch on error.data.code — the string is stable. error.code is the JSON-RPC number tRPC maps it to, and error.message is written for engineers, not for your end users.
{
"error": {
"message": "Rate limit exceeded. Please try again in 60 seconds.",
"code": -32029,
"data": {
"code": "TOO_MANY_REQUESTS",
"httpStatus": 429,
"path": "artists.topGaining"
}
}
}Limits & credits
The rate limit is 30 requests per minute per user, whether you call the endpoints directly or go through an MCP tool: the two share one budget. Splitting work across several tokens does not buy headroom, because the limit is counted per user, not per token.
Two arguments are bounded by your plan rather than by the API. How far back date can go, and how deep offset pagination can reach, both depend on the plan you are on. Asking for a date or an offset past your limit returns FORBIDDEN, and the message names the limit you hit.
Looking up details for an artist, track or playlist you do not already follow spends one of your plan’s daily browse credits. Anything you follow is free to browse as often as you like — so if a job polls the same catalogue every day, follow it once from the app instead of paying a credit each morning.
Charts
Music24's daily leaderboards: who is gaining, who is on top, right now.
curl 'https://api.musicapi.com/trpc/playlists.trending?input=%7B%22json%22%3A%7B%22limit%22%3A3%7D%7D' \ -H 'Authorization: Token m24_xxxxxxxxxxxxxxxxxxxxxxxx'
{
"result": {
"data": {
"json": {
"playlists": [
{
"playlistId": "b6b6a1e2-...",
"name": "Rap Caviar",
"curatorName": "Spotify",
"followersGain": 18420,
"position": 1,
"integrationType": "spotify"
}
],
"pagination": { "offset": 0, "limit": 3 }
}
}
}
}Details
One artist, track, or playlist at a time — profile plus history.
curl 'https://api.musicapi.com/trpc/artists.details?input=%7B%22json%22%3A%7B%22artistId%22%3A%222ab91f6e-...%22%7D%7D' \ -H 'Authorization: Token m24_xxxxxxxxxxxxxxxxxxxxxxxx'
{
"result": {
"data": {
"json": {
"maid": "2ab91f6e-...",
"mainName": "Role Model",
"imageUrl": "https://.../role-model.jpg"
}
}
}
}Your data
The artists, tracks, and playlists the authenticated user follows on Music24, plus that same user’s daily and weekly digest reports.
curl 'https://api.musicapi.com/trpc/artists.followedArtists?input=%7B%22json%22%3A%7B%22limit%22%3A10%7D%7D' \ -H 'Authorization: Token m24_xxxxxxxxxxxxxxxxxxxxxxxx'
{
"result": {
"data": {
"json": {
"artists": [
{ "id": 501, "maid": "2ab91f6e-...", "mainName": "Role Model", "imageUrl": "https://.../role-model.jpg" }
],
"total": 37,
"hasMore": true
}
}
}
}Insights
Statistical signals computed on top of the daily chart data.
curl 'https://api.musicapi.com/trpc/insights.trendingUp?input=%7B%22json%22%3A%7B%22entityType%22%3A%22artist%22%2C%22limit%22%3A3%7D%7D' \ -H 'Authorization: Token m24_xxxxxxxxxxxxxxxxxxxxxxxx'
{
"result": {
"data": {
"json": {
"rows": [
{
"date": "2026-08-28",
"entityType": "artist",
"id": "2ab91f6e-...",
"name": "Role Model",
"value": 41200,
"pctChange7d": 0.18,
"pctChange30d": 0.44
}
],
"hasMore": false
}
}
}
}MCP server
Music24 runs a remote MCP server over Streamable HTTP at https://api.musicapi.com/mcp. Point any MCP-compatible client — Claude, Cursor or your own agent — at that URL and it connects with OAuth, not with a personal access token. Like the rest of the API, this needs the Pro plan.
The client discovers everything itself. It reads the two well-known endpoints, registers itself under RFC 7591 with no manual setup, then runs the standard authorization-code + PKCE (S256) flow requesting scope music24:read. A completed flow returns an access token good for one hour and a refresh token good for 30 days, rotating on use — the old refresh token dies the moment a new one is issued.
Tools
music24_playlist_changes is scoped to the one playlist you give it by id — it is not a feed across everything you follow. Call music24_my_follows first to get the ids worth asking about.
https://api.musicapi.com/mcpGET https://api.musicapi.com/.well-known/oauth-protected-resource → points at the authorization server: GET https://api.freeyourmusic.com/.well-known/oauth-authorization-server