Skip to content

Versions

leanwrldd edited this page Sep 10, 2026 · 2 revisions

← Back to Home

Versions

What is the Versions API?

Groups multiple song rows together as versions of the same underlying track — e.g. a released mix and a leaked earlier take, or several titled variants like "v1", "v2", "TV Mix". Each row links one song_id to a shared group_id; every song in a group shares the same title (the display name for the group, e.g. "She's The One"), while each song keeps its own version label (e.g. "v1") distinguishing it from its groupmates.

Reads require no auth. Writes (POST/PATCH) require an editor or admin token.

Version Row Shape

{
  "id": 501,
  "song_id": 94086,
  "group_id": 94086,
  "version": "v1",
  "title": "She's The One",
  "created_at": "2026-03-04T12:00:00Z",
  "created_by": "freakypallet"
}

group_id is just the song_id of whichever song originally anchored the group — it has no meaning beyond being a shared key. title is null until an editor names the group; version is null until an editor labels that specific song.

GET /versions/{song_id}/ — This Song's Row

The one filtered read the API supports server-side. Returns the paginated envelope with 0 or 1 result — empty means the song isn't linked into any group.

{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [ { "id": 501, "song_id": 94086, "group_id": 94086, "version": "v1", "title": "She's The One", ... } ]
}

GET /versions/{song_id}/{id}/ fetches a single version row directly by its own id, unpaginated, instead of the song-filtered list above.

GET /versions/ — All Rows

The list endpoint does not apply query params (group_id, search, title) server-side — any filtering by group or title has to happen client-side. Pass ?all=true to get every row in one response instead of paging through it (same bulk-mode convention /songs/ supports).

GET /versions/?all=true

// Response: a plain array (not the paginated envelope)
[
  { "id": 501, "song_id": 94086, "group_id": 94086, "version": "v1",   "title": "She's The One", ... },
  { "id": 502, "song_id": 94112, "group_id": 94086, "version": "v2",   "title": "She's The One", ... },
  { "id": 503, "song_id": 95230, "group_id": 95230, "version": null,   "title": null, ... }
]

POST /versions/ — Create a Row (editor+)

POST /versions/
Authorization: Token <token>
Content-Type: application/json

{
  "song_id": 94112,
  "group_id": 94086,
  "version": "v2",
  "title": "She's The One"
}

Used both to link a previously-ungrouped song into an existing group and to seed a brand-new group (pass a group_id no other row uses yet — the app conventionally uses one of the two songs' own song_id).

PATCH /versions/{song_id}/ — Update a Row (editor+)

PATCH /versions/{song_id}/
Authorization: Token <token>
Content-Type: application/json

{ "group_id": 94086, "title": "She's The One" }

Any subset of group_id, version, title may be sent. There is no bulk-write endpoint — merging two groups or renaming a group's title means sending one PATCH per affected song.

Common Operations (client-side recipes)

  • Link two ungrouped songs: create two rows sharing a new group_id (e.g. the lower of the two song IDs).
  • Add an ungrouped song to an existing group: POST one row with that group's group_id and title.
  • Merge two existing groups: fetch every row in both groups (via ?all=true), then PATCH every row in the losing group to the surviving group_id — and if only one side had a title set, PATCH that title onto every row in the merged group so all members agree.
  • Rename a group's title: PATCH { title } onto every row whose group_id matches.

Clone this wiki locally