Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions content/en/docs/Endpoints/createplaylistfolder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
title: "createPlaylistFolder"
linkTitle: "createPlaylistFolder [OS]"
OpenSubsonic:
- Extension
categories:
- Playlists
description: >
Creates a playlist folder.
---

**OpenSubsonic version**: [1](../../opensubsonic-versions)

**OpenSubsonic extension name** `playlistFolders` (As returned by [`getOpenSubsonicExtensions`](../../endpoints/getopensubsonicextensions))

`http://your-server/rest/createPlaylistFolder`

Creates a playlist folder in the authenticated user's playlist organization.

### Parameters

| Parameter | Req. | OpenS. | Default | Comment |
| --- | --- | --- | --- | --- |
| `name` | **Yes** | **Yes** | | The human-readable name of the playlist folder. |
| `parentId` | No | **Yes** | | ID of the parent playlist folder. Omit to create a root-level folder. |
| `sortOrder` | No | **Yes** | | Position among siblings, as a client-assigned integer. If omitted, the server assigns a position after the existing siblings. |

A `parentId` that does not exist or belongs to another user's tree returns error `70`, so that a user cannot probe for folder IDs in other users' trees. See the [extension description](../../extensions/playlistfolders) for ordering semantics and error handling.

### Example

{{< alert color="primary" >}} `http://your-server/rest/createPlaylistFolder.view?name=2026&parentId=folder-dj&u=demo&p=demo&v=1.16.1&c=AwesomeClientName&f=json` {{< /alert >}}

### Result

A [`subsonic-response`](../../responses/subsonic-response) element with a nested [`playlistFolder`](../../responses/playlistfolder) element on success.

{{< tabpane persist=false >}}
{{< tab header="**Example**:" disabled=true />}}
{{< tab header="OpenSubsonic" lang="json">}}
{
"subsonic-response": {
"status": "ok",
"version": "1.16.1",
"type": "AwesomeServerName",
"serverVersion": "0.1.3 (tag)",
"openSubsonic": true,
"playlistFolder": {
"id": "folder-2026",
"name": "2026",
"parentId": "folder-dj",
"sortOrder": 2
}
}
}
{{< /tab >}}
{{< tab header="Subsonic" >}}
Does not exist.
{{< /tab >}}
{{< /tabpane >}}

{{< alert color="warning" title="OpenSubsonic" >}}
This is a new extension endpoint.
{{< /alert >}}
56 changes: 56 additions & 0 deletions content/en/docs/Endpoints/deleteplaylistfolder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
title: "deletePlaylistFolder"
linkTitle: "deletePlaylistFolder [OS]"
OpenSubsonic:
- Extension
categories:
- Playlists
description: >
Deletes an empty playlist folder.
---

**OpenSubsonic version**: [1](../../opensubsonic-versions)

**OpenSubsonic extension name** `playlistFolders` (As returned by [`getOpenSubsonicExtensions`](../../endpoints/getopensubsonicextensions))

`http://your-server/rest/deletePlaylistFolder`

Deletes an empty folder from the authenticated user's playlist organization.

### Parameters

| Parameter | Req. | OpenS. | Default | Comment |
| --- | --- | --- | --- | --- |
| `playlistFolderId` | **Yes** | **Yes** | | ID of the playlist folder to delete. |

The folder must contain no child folders and no playlists currently visible to the user. A server must return error `0` when the folder is not empty and must not implicitly delete or move its contents. A `playlistFolderId` that does not exist or belongs to another user's tree returns error `70`. See the [extension description](../../extensions/playlistfolders) for the placement lifecycle and error handling.

### Example

{{< alert color="primary" >}} `http://your-server/rest/deletePlaylistFolder.view?playlistFolderId=folder-2026&u=demo&p=demo&v=1.16.1&c=AwesomeClientName&f=json` {{< /alert >}}

### Result

An empty [`subsonic-response`](../../responses/subsonic-response) element on success.

{{< tabpane persist=false >}}
{{< tab header="**Example**:" disabled=true />}}
{{< tab header="OpenSubsonic" lang="json">}}
{
"subsonic-response": {
"status": "ok",
"version": "1.16.1",
"type": "AwesomeServerName",
"serverVersion": "0.1.3 (tag)",
"openSubsonic": true
}
}
{{< /tab >}}
{{< tab header="Subsonic" >}}
Does not exist.
{{< /tab >}}
{{< /tabpane >}}

{{< alert color="warning" title="OpenSubsonic" >}}
This is a new extension endpoint.
{{< /alert >}}
69 changes: 69 additions & 0 deletions content/en/docs/Endpoints/getplaylistfolders.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
title: "getPlaylistFolders"
linkTitle: "getPlaylistFolders [OS]"
OpenSubsonic:
- Extension
categories:
- Playlists
description: >
Returns all folders in a user's playlist organization.
---

**OpenSubsonic version**: [1](../../opensubsonic-versions)

**OpenSubsonic extension name** `playlistFolders` (As returned by [`getOpenSubsonicExtensions`](../../endpoints/getopensubsonicextensions))

`http://your-server/rest/getPlaylistFolders`

Returns all folders in a user's playlist organization as a flat list. Clients build the hierarchy by matching each folder's `parentId` to another folder's `id`, and place playlists using the `playlistFolderId` returned by [`getPlaylists`](../getplaylists).

### Parameters

| Parameter | Req. | OpenS. | Default | Comment |
| --- | --- | --- | --- | --- |
| `username` | No | **Yes** | | If specified, return folders for this user rather than for the authenticated user. The authenticated user must have admin role if this parameter is used. |

### Example

{{< alert color="primary" >}} `http://your-server/rest/getPlaylistFolders.view?u=demo&p=demo&v=1.16.1&c=AwesomeClientName&f=json` {{< /alert >}}

### Result

A [`subsonic-response`](../../responses/subsonic-response) element with a nested [`playlistFolders`](../../responses/playlistfolders) element on success.

{{< tabpane persist=false >}}
{{< tab header="**Example**:" disabled=true />}}
{{< tab header="OpenSubsonic" lang="json">}}
{
"subsonic-response": {
"status": "ok",
"version": "1.16.1",
"type": "AwesomeServerName",
"serverVersion": "0.1.3 (tag)",
"openSubsonic": true,
"playlistFolders": {
"playlistFolder": [
{
"id": "folder-dj",
"name": "DJ Sets",
"sortOrder": 1
},
{
"id": "folder-2026",
"name": "2026",
"parentId": "folder-dj",
"sortOrder": 1
}
]
}
}
}
{{< /tab >}}
{{< tab header="Subsonic" >}}
Does not exist.
{{< /tab >}}
{{< /tabpane >}}

{{< alert color="warning" title="OpenSubsonic" >}}
This is a new extension endpoint.
{{< /alert >}}
58 changes: 58 additions & 0 deletions content/en/docs/Endpoints/moveplaylist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
title: "movePlaylist"
linkTitle: "movePlaylist [OS]"
OpenSubsonic:
- Extension
categories:
- Playlists
description: >
Places playlists in a folder or at the root and sets their position.
---

**OpenSubsonic version**: [1](../../opensubsonic-versions)

**OpenSubsonic extension name** `playlistFolders` (As returned by [`getOpenSubsonicExtensions`](../../endpoints/getopensubsonicextensions))

`http://your-server/rest/movePlaylist`

Places playlists in the authenticated user's playlist organization. This endpoint moves playlists into a folder or to the root and sets their position among siblings. It never modifies the playlists themselves, so it works on any playlist visible to the user, including shared, public, and `readonly` playlists owned by others.

### Parameters

| Parameter | Req. | OpenS. | Default | Comment |
| --- | --- | --- | --- | --- |
| `playlistId` | **Yes** | **Yes** | | ID of the playlist to place. Multiple parameters allowed; playlists are placed in the order given. |
| `playlistFolderId` | No | **Yes** | | ID of the destination folder. An empty value moves the playlists to the root. Omit to keep each playlist in its current location and only change its position. |
| `sortOrder` | No | **Yes** | | Position among siblings, as a client-assigned integer. Multiple parameters allowed, paired in order with `playlistId` (as `time` pairs with `id` on [`scrobble`](../scrobble)). When omitted, moved playlists are placed after the existing contents of the destination. |

At least one of `playlistFolderId` or `sortOrder` must be supplied; otherwise the server returns error `10`. When `sortOrder` parameters are supplied, their count must match the number of `playlistId` parameters; otherwise the server returns error `10`. See the [extension description](../../extensions/playlistfolders) for ordering semantics and error handling.

### Example

{{< alert color="primary" >}} `http://your-server/rest/movePlaylist.view?playlistId=playlist-summer&playlistFolderId=folder-2026&sortOrder=3&u=demo&p=demo&v=1.16.1&c=AwesomeClientName&f=json` {{< /alert >}}

### Result

An empty [`subsonic-response`](../../responses/subsonic-response) element on success.

{{< tabpane persist=false >}}
{{< tab header="**Example**:" disabled=true />}}
{{< tab header="OpenSubsonic" lang="json">}}
{
"subsonic-response": {
"status": "ok",
"version": "1.16.1",
"type": "AwesomeServerName",
"serverVersion": "0.1.3 (tag)",
"openSubsonic": true
}
}
{{< /tab >}}
{{< tab header="Subsonic" >}}
Does not exist.
{{< /tab >}}
{{< /tabpane >}}

{{< alert color="warning" title="OpenSubsonic" >}}
This is a new extension endpoint.
{{< /alert >}}
59 changes: 59 additions & 0 deletions content/en/docs/Endpoints/updateplaylistfolder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
title: "updatePlaylistFolder"
linkTitle: "updatePlaylistFolder [OS]"
OpenSubsonic:
- Extension
categories:
- Playlists
description: >
Renames, moves, or reorders a playlist folder.
---

**OpenSubsonic version**: [1](../../opensubsonic-versions)

**OpenSubsonic extension name** `playlistFolders` (As returned by [`getOpenSubsonicExtensions`](../../endpoints/getopensubsonicextensions))

`http://your-server/rest/updatePlaylistFolder`

Updates a folder in the authenticated user's playlist organization: rename it, move it under another folder or to the root, or change its position among its siblings. Playlists are moved into and out of folders with [`movePlaylist`](../moveplaylist).

### Parameters

| Parameter | Req. | OpenS. | Default | Comment |
| --- | --- | --- | --- | --- |
| `playlistFolderId` | **Yes** | **Yes** | | ID of the playlist folder to update. |
| `name` | No | **Yes** | | The new human-readable name. |
| `parentId` | No | **Yes** | | ID of the new parent folder. An empty value moves the folder to the root. Omit to leave the parent unchanged. |
| `sortOrder` | No | **Yes** | | New position among siblings, as a client-assigned integer. |

At least one optional parameter must be supplied; otherwise the server returns error `10`. A `parentId` that does not exist or belongs to another user's tree returns error `70`; a move that would create a cycle returns error `0`. See the [extension description](../../extensions/playlistfolders) for ordering semantics and error handling.

### Example

{{< alert color="primary" >}} `http://your-server/rest/updatePlaylistFolder.view?playlistFolderId=folder-2026&parentId=folder-dj&sortOrder=1&u=demo&p=demo&v=1.16.1&c=AwesomeClientName&f=json` {{< /alert >}}

### Result

An empty [`subsonic-response`](../../responses/subsonic-response) element on success.

{{< tabpane persist=false >}}
{{< tab header="**Example**:" disabled=true />}}
{{< tab header="OpenSubsonic" lang="json">}}
{
"subsonic-response": {
"status": "ok",
"version": "1.16.1",
"type": "AwesomeServerName",
"serverVersion": "0.1.3 (tag)",
"openSubsonic": true
}
}
{{< /tab >}}
{{< tab header="Subsonic" >}}
Does not exist.
{{< /tab >}}
{{< /tabpane >}}

{{< alert color="warning" title="OpenSubsonic" >}}
This is a new extension endpoint.
{{< /alert >}}
55 changes: 55 additions & 0 deletions content/en/docs/Extensions/playlistFolders.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
title: "Playlist Folders"
linkTitle: "Playlist Folders"
OpenSubsonic:
- Extension
description: >
Adds private, per-user folders and nested folders for organizing playlists.
---

**OpenSubsonic version**: [1](../../opensubsonic-versions)

**OpenSubsonic extension name** `playlistFolders` (As returned by [`getOpenSubsonicExtensions`](../../endpoints/getopensubsonicextensions))

When a server supports this extension, each user can organize the playlists available to them in ordered folders of arbitrary depth, as in iTunes/Apple Music, Spotify, or Rekordbox. Existing clients remain compatible because [`getPlaylists`](../../endpoints/getplaylists) continues to return every visible playlist as a flat list.

## Version 1

This extension requires the following endpoints:

- [`createPlaylistFolder`](../../endpoints/createplaylistfolder) creates a folder.
- [`deletePlaylistFolder`](../../endpoints/deleteplaylistfolder) deletes an empty folder.
- [`getPlaylistFolders`](../../endpoints/getplaylistfolders) returns all of the selected user's folders.
- [`movePlaylist`](../../endpoints/moveplaylist) places playlists in a folder or at the root and sets their position.
- [`updatePlaylistFolder`](../../endpoints/updateplaylistfolder) renames, moves, or reorders a folder.

It also adds `playlistFolderId` and `playlistFolderSortOrder` to the [`playlist`](../../responses/playlist) response.

### Hierarchy and user scope

[`getPlaylistFolders`](../../endpoints/getplaylistfolders) returns a flat list. A folder's optional `parentId` identifies its parent; no `parentId` means that the folder is at the root. This representation supports arbitrary nesting without recursive responses. Clients reconstruct the full tree from two requests: [`getPlaylistFolders`](../../endpoints/getplaylistfolders) for the folders and [`getPlaylists`](../../endpoints/getplaylists) for the playlists, using each playlist's `playlistFolderId`.

A user's folder tree is private to that user, and folder placement is independent of playlist ownership. A user can place any playlist visible to them — including a public or shared playlist owned by another user, or a `readonly` one — without modifying the playlist itself. Different users can place the same playlist in different folders; within one user's tree a playlist has at most one placement. Folder names do not have to be unique.

The selected user is the authenticated user, or the user named by the admin-only `username` parameter on [`getPlaylists`](../../endpoints/getplaylists) and [`getPlaylistFolders`](../../endpoints/getplaylistfolders). Servers must never expose one user's folders or placements to another user.

### Ordering

Sibling items — the child folders and playlists sharing one parent, or the folders and playlists at the root — share a single ordering space. `sortOrder` values are client-assigned integers that servers store without normalization; duplicates are allowed. Clients should sort siblings by `sortOrder` ascending, breaking ties by name, and place items without a value after ordered ones. This lets clients reproduce manually ordered trees from apps like iTunes and Rekordbox exactly.

### Placement lifecycle and deletion

A placement exists only while its playlist is visible to the user: when a playlist is deleted or stops being visible, its placement in every affected user's tree ceases to exist. Folder emptiness is evaluated over child folders and currently visible playlists. Folders can only be deleted when empty; servers must not implicitly delete or move a folder's contents.

An omitted `parentId` on [`updatePlaylistFolder`](../../endpoints/updateplaylistfolder) leaves the folder's parent unchanged, while an explicitly empty value moves the folder to the root. The `playlistFolderId` parameter of [`movePlaylist`](../../endpoints/moveplaylist) behaves the same way. Servers must distinguish an empty parameter value from an absent parameter.

### Error handling

- A folder ID (including `parentId`) that does not exist or belongs to another user's tree returns error `70`, indistinguishable from not-found, so that folder IDs cannot be probed across users.
- A `playlistId` that does not exist or is not visible to the authenticated user returns error `70`.
- A move that would create a cycle, or deleting a non-empty folder, returns error `0`.
- Calling [`updatePlaylistFolder`](../../endpoints/updateplaylistfolder) or [`movePlaylist`](../../endpoints/moveplaylist) without any of their optional parameters returns error `10`.

### Backward compatibility

Clients that do not support this extension can keep using the existing playlist endpoints. They receive the same complete flat playlist list and can ignore the new fields.
Loading