Appearance
scrobble-links
17 endpoints at a glance
| Method | Path | Summary |
|---|---|---|
DELETE | /admin/scrobble-links/{username} | Admin Delete Link |
POST | /admin/scrobble-links/{username} | Admin Add Link |
POST | /admin/scrobble-links/{username}/auto-link | Admin Auto Link |
GET | /admin/scrobble-links/{username}/linked | Admin Linked |
GET | /admin/scrobble-links/{username}/stats | Admin Stats |
GET | /admin/scrobble-links/{username}/unlinked | Admin Unlinked |
POST | /admin/scrobble-links/reconcile-all | Admin Reconcile All |
POST | /admin/scrobble-links/relink-album/{album_id} | Admin Relink By Album |
POST | /admin/scrobble-links/relink-all | Admin Relink All |
POST | /admin/scrobble-links/relink-artist/{artist_id} | Admin Relink By Artist |
GET | /admin/scrobble-links/users | Admin Users |
DELETE | /me/scrobble-links | My Delete Link |
POST | /me/scrobble-links | My Add Link |
POST | /me/scrobble-links/auto-link | My Auto Link |
GET | /me/scrobble-links/linked | My Linked |
GET | /me/scrobble-links/stats | My Stats |
GET | /me/scrobble-links/unlinked | My Unlinked |
scrobble-links
My Stats
My Unlinked
My Linked
My Add Link
My Delete Link
My Auto Link
POST
/me/scrobble-links/auto-link
Run the auto-linker against the caller's scrobbles right now.
only_unlinked=True (default) is fast; False re-evaluates
every scrobble (useful after canonical priorities change).
Parameters
Query Parameters
only_unlinked
Type
boolean
Default
trueResponses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Admin Users
Admin Stats
Admin Unlinked
GET
/admin/scrobble-links/{username}/unlinked
Parameters
Path Parameters
username*
Type
Requiredstring
Query Parameters
kind*
Type
Requiredstring
Valid values
"artist""album""track"limit
Type
integer
Default
50skip
Type
integer
Default
0Responses
Successful Response
application/json
JSON { "additionalProperties": "string" }
[
]
Admin Linked
GET
/admin/scrobble-links/{username}/linked
Parameters
Path Parameters
username*
Type
Requiredstring
Query Parameters
kind*
Type
Requiredstring
Valid values
"artist""album""track"limit
Type
integer
Default
50skip
Type
integer
Default
0Responses
Successful Response
application/json
JSON { "additionalProperties": "string" }
[
]
Admin Reconcile All
POST
/admin/scrobble-links/reconcile-all
Fire-and-forget version of the nightly auto-link reconciler.
Walking every user's scrobbles can take minutes on heavy
listeners — far past the SPA's HTTP timeout. The work runs on the
event loop; the SPA polls /admin/task-history/{task_id}.
Incremental: only touches scrobbles missing at least one
canonical_*_id. Cheap. Run nightly.
Parameters
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Admin Relink By Artist
POST
/admin/scrobble-links/relink-artist/{artist_id}
Force-relink every scrobble whose artist matches this canonical's name.
Targeted version of relink-all for fixing the
"scrobbles point at a duplicate canonical" symptom: when the user
has linked all sources to canonical X but some "Pink Floyd"
scrobbles still resolve to canonical Y (a duplicate), this
endpoint walks every scrobble where artist.name folds to X's
name and re-runs compute_canonical_ids. The tiebreaker added
in 1b ensures the most-sourced canonical wins → all scrobbles
converge on X without manual per-scrobble action.
Force-mode is the only mode: this endpoint overwrites existing
canonical_artist_id on every matching scrobble. That's the
explicit user intent — they're asserting "X is the right
canonical for this name." Bounded blast radius: only scrobbles
with this folded name are touched.
Synchronous (not background-task'd) because the work is small —
one user's "Pink Floyd" scrobbles is at most a few thousand docs,
not the millions a full relink-all touches.
Parameters
Path Parameters
artist_id*
Type
Requiredstring
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Admin Relink By Album
POST
/admin/scrobble-links/relink-album/{album_id}
Repair cross-artist album collisions for a canonical album.
Before the auto-linker's title-only fallback was removed, a
scrobble for artist A's album (e.g. The Beatles' "Let It Be")
with no matching canonical album under A could be stamped with
artist B's same-titled canonical album (The Replacements' "Let It
Be") via a title-only title_folded match. The album detail page
then surfaced the wrong artist's scrobble stats (Path 1 of
album_stats keys off canonical_album_id).
This re-runs the now-artist-scoped compute_canonical_ids over
two sets and overwrites their canonical pointers:
- scrobbles currently pointing here (
canonical_album_id == album_id) — the mis-stamped foreign-artist ones re-resolve to
None(or to their own album) and drop off; the genuine ones
stay; - scrobbles whose (artist, album) names fold to this canonical's
(artist_name, title) — re-links any that legitimately belong here
but were previously missed.
Synchronous: bounded to one album's worth of matching scrobbles.
The auto-linker fix prevents new mis-stamps; this cleans up the
ones already in the bank vault. Scrobbles are never deleted — only
their derived canonical pointers are recomputed.
Parameters
Path Parameters
album_id*
Type
Requiredstring
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Admin Relink All
POST
/admin/scrobble-links/relink-all
Full rebuild — re-evaluates every scrobble.
Distinct from reconcile-all: this one re-evaluates already-
linked scrobbles too. Use after:
- canonical merges (stale
canonical_*_idshould follow to
the survivor — without this, dashboards show "unlinked" for
scrobbles that point at tombstones) - a Plex / MB enrichment that minted new canonicals and you want
old scrobbles to pick them up even though they were already
linked at the artist level - any priority-table or projector change that would have produced
different links if it had been in place at ingest time
Slower than reconcile-all because it walks every scrobble, not
just unlinked ones. Still fire-and-forget; the SPA polls
/admin/task-history/{task_id}.
Parameters
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Admin Add Link
POST
/admin/scrobble-links/{username}
Parameters
Path Parameters
username*
Type
Requiredstring
Request Body
application/json
JSON "kind": "string", "artist_name": "string", "album_name": "string", "track_name": "string", "canonical_id": "string", "unmatchable": false
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Admin Delete Link
DELETE
/admin/scrobble-links/{username}
Parameters
Path Parameters
username*
Type
Requiredstring
Request Body
application/json
JSON "kind": "string", "artist_name": "string", "album_name": "string", "track_name": "string"
{
}
Responses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}
Admin Auto Link
POST
/admin/scrobble-links/{username}/auto-link
Fire-and-forget per-user auto-link.
A heavy listener's "re-link everything" run easily exceeds the
SPA's 15s timeout (we walk every scrobble). The SPA polls
/admin/task-history/{task_id}.
Parameters
Path Parameters
username*
Type
Requiredstring
Query Parameters
only_unlinked
Type
boolean
Default
trueResponses
Successful Response
application/json
JSON "additionalProperties": "string"
{
}