> For the complete documentation index, see [llms.txt](https://wiki.crosswatch.app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.crosswatch.app/crosswatch/main-dashboard/navigation/playlists.md).

# Playlists

Keep lists in sync between providers and publish lists for other tools.

Keep lists in sync between your providers, and publish lists for Kometa, Radarr and Sonarr.

Use **Playlists** for named lists you choose, such as Plex playlists, Trakt lists or a watchlist you want copied somewhere else.

Playlists differ from **Watchlist** sync. Watchlist sync manages a provider's standard plan-to-watch list as part of a normal sync pair.

Open **Main Dashboard → Playlists**.

The page has two views:

| View                 | For            | Shows                                                    |
| -------------------- | -------------- | -------------------------------------------------------- |
| **Simple** (default) | Everyday use   | List syncs, Lists and Published lists, in plain words.   |
| **Advanced**         | Complex setups | Endpoints, mappings, rulesets and the activity overview. |

Switch with the **Advanced** button at the top. Your choice is remembered.

### Before you start

Connect at least one compatible provider in **Connections**.

Plex, Trakt, MDBList, Jellyfin, Emby, PublicMetaDB, SIMKL, and CrossWatch support playlists when configured.

Available actions depend on each provider and list. A list may be read-only.

> **SIMKL:** SIMKL offers two kinds of lists.
>
> * **Status buckets** (Plan to Watch, Watching, On Hold, Dropped, Completed) can be read and written. They are not true playlists: changing one can move or remove items from your SIMKL library.
> * **Custom lists** are read-only and need SIMKL PRO or VIP. Use them as the source of a sync.

### How the page is organized

#### List syncs

A list sync keeps one list up to date with another. Each row shows:

* **From** and **To**: the two lists and their providers.
* **How**: Add only, Keep in sync, or Exact copy.
* **Last result**: the outcome and time of the latest run.
* **Actions**: Review and sync, pause or resume, edit, delete.

**History** opens all activity.

#### Lists

The provider lists CrossWatch can use. Each row shows the list, its type (Watchlist, Playlist, Collection, Custom list, Status, Discovery), its item count and when it was last checked.

You do not have to add lists here first. Creating a sync adds the lists it needs.

#### Published lists

CrossWatch lists that Kometa, Radarr or Sonarr can read through a web address.

See [Published lists](/crosswatch/main-dashboard/navigation/playlists/published-lists.md) for setup, supported formats and troubleshooting.

### Create a sync

1. Select **New sync**.
2. **From:** choose the provider, then the list to read.
3. **To:** choose where the items should go.
   * **A list on a provider:** choose the provider and the list, or **Create a new list...** and give it a name.
   * **Kometa, Radarr or Sonarr:** give the list a name. CrossWatch creates and publishes it.
4. **How:** choose what CrossWatch may change in the destination.
5. Select **Create sync**.

CrossWatch adds the lists it needs and creates the sync. A list you added before is reused.

Only lists that can be written are offered as a destination. Read-only lists, such as SIMKL custom lists and discovery lists, can only be a source.

#### How a list is kept up to date

| Choice           | What it does                                                                                                        | Use it when                                |
| ---------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
| **Add only**     | Adds missing items. Never removes anything from the destination.                                                    | You also manage the destination by hand.   |
| **Keep in sync** | Adds missing items and removes the ones CrossWatch added earlier. Items you added to the destination yourself stay. | Most setups. This is the default.          |
| **Exact copy**   | Makes the destination match the source. Can remove items you added there yourself.                                  | The source fully controls the destination. |

A discovery source, such as Trakt Recommended, is always an exact copy.

### Run and review a sync

Select **Review and sync** on a list sync. It opens Interactive Sync for that sync.

Interactive Sync reads both lists, shows the proposed additions and removals, and applies what you select. The back link returns you to Playlists.

CrossWatch blocks conflicting runs while a synchronization is active.

A run that could not start, for example because the source list no longer exists, is shown as **Failed**. Hover the Failed label to read the reason.

A successful run can include unresolved items. CrossWatch could not safely match or write them.

### Edit, pause or delete a sync

**Edit** opens a small dialog where you can change how the list is kept up to date and switch the sync between active and paused. **More settings** opens the full dialog from the Advanced view.

To change the lists themselves, create a new sync.

**Pause** keeps the sync but skips it. **Delete** removes the sync. It does not delete either list.

### Add, change or remove a list

**Add list** lets you pick the provider and one or more lists. The profile step only appears when the provider has more than one profile.

**Refresh** reloads the list details and item count. It does not run a sync. Refresh a list after renaming or recreating it on the provider.

**Change list** selects another provider list for that entry.

**Remove list** removes only the CrossWatch reference. Check that no sync still uses it. The list on the provider is kept.

The list picker may also offer create, rename or delete actions. Those change the real list on the provider.

### Smart and special lists

Smart, discovery, virtual, built-in, watchlist, and SIMKL custom list resources can have limited capabilities.

CrossWatch only enables actions that the provider and list support.

### Recommended first setup

1. Select **New sync**.
2. Pick one source list and one destination list.
3. Keep **Keep in sync**.
4. Run **Review and sync** and check the proposed changes.
5. Review the result.

Use Exact copy or the Advanced view only after this setup works as expected.

## Advanced view

Select **Advanced** to work with the building blocks directly. Use it for splitting large lists, merging several lists, limited account sharing, ordering, and custom rulesets.

The simple view and the Advanced view show the same data under different names:

| Simple view                          | Advanced view                                     |
| ------------------------------------ | ------------------------------------------------- |
| List                                 | Playlist endpoint                                 |
| List sync                            | Mapping                                           |
| Add only / Keep in sync / Exact copy | Membership `add_only` / `managed_only` / `mirror` |
| History                              | Activity overview                                 |

### Playlist endpoints

An endpoint connects CrossWatch to one list on one provider profile. It records the provider, profile and selected provider list, and has its own short name.

1. Select **Add endpoint**.
2. Enter a name, and choose the provider and profile.
3. Select the provider playlist.
4. Save the endpoint.

### Mappings

A mapping connects one source endpoint to a destination endpoint.

1. Select **New mapping**.
2. Choose the source endpoint and a different destination endpoint.
3. Select a ruleset, sync mode and ordering.
4. Save the mapping.

CrossWatch associates the mapping with a compatible sync pair.

#### Choose a ruleset

Use **Direct sync** for most setups. It synchronizes one source with one destination.

Other presets support source mirroring, large-list splitting, playlist merging, or limited account sharing.

Choose **Custom** only when you need detailed ruleset settings.

### Playlist order

Use **Preserve** to request the source order on the destination.

If reordering is unsupported, CrossWatch reports a warning.

### Activity overview

Activity overview shows the latest result of each mapping, including failed runs, and counts them by outcome.

Select **View all activity** for more history.

### Technical reference

This reference covers playlist resources, endpoints, mappings, rulesets, pairs, published lists, and runtime state.

### Mental model

Playlist synchronization uses four related objects.

#### Provider resource

A provider resource is a playlist-like object returned by a provider adapter.

```
provider
instance
id
name
kind
can_read
can_add
can_remove
can_reorder
media_types
extra
```

CrossWatch also derives flags such as `smart`, `writable`, `discovery`, and `endpoint_type`.

#### Endpoint

An endpoint references one provider resource.

```
playlists.endpoints
```

```
id
name
provider
instance
playlist_id
playlist_name
playlist_type
media_types
pending_create
```

`instance` identifies the provider profile shown as **Profile** in the UI.

#### Mapping

A mapping connects one source endpoint to one or more target endpoints.

```
playlists.mappings
```

```
id
name
source_endpoint
target_endpoints
ruleset_id
membership
order
enabled
allow_mass_delete
```

The UI selects one destination. Internally, `target_endpoints` remains a list.

Aggregate and partition rulesets can use several target endpoints.

#### Ruleset

A ruleset controls direction, membership, ordering, aggregation, partitioning, capacities, and assignment.

```
playlists.rulesets
```

Built-in rulesets are runtime-managed. They cannot be edited or deleted.

### What the simple view creates

**New sync** uses the same objects as the Advanced view:

* one endpoint per list, reusing an endpoint that already points at the same provider, profile and list;
* a direct mapping without a ruleset, with the chosen membership and `order = ignore`;
* for the Kometa, Radarr or Sonarr destination: a new CrossWatch list, its endpoint, and a published address.

Endpoint and mapping names are generated (`EP-01`, `MAP-01`). The simple edit dialog changes `membership` and `enabled` only.

### Provider contract and protection

Playlist-capable providers implement these core operations:

```
list_playlist_resources
get_playlist_snapshot
create_playlist
add_playlist_items
remove_playlist_items
reorder_playlist_items
```

They can also expose `rename_playlist` and `delete_playlist`.

Capability metadata controls available UI actions.

```
read
create
create_empty
create_endpoint_types
rename
delete
add
remove
reorder
smart
smart_writable
media_types
endpoint_types
ordered_endpoint_types
unordered_endpoint_types
```

Plex, Trakt, MDBList, Jellyfin, Emby, PublicMetaDB, SIMKL, and CrossWatch support playlists when configured.

Protected resources cannot be renamed or deleted. These include smart, discovery, virtual, built-in, and watchlist resources.

A manageable resource also needs a valid provider resource ID.

Plex distinguishes playlists, collections, and watchlist-like resources. Only regular playlists support ordering.

### SIMKL behavior

SIMKL exposes two endpoint types.

| Type                            | ID                                                        | Read | Write |
| ------------------------------- | --------------------------------------------------------- | ---- | ----- |
| Status bucket (`status_bucket`) | `plantowatch`, `watching`, `hold`, `dropped`, `completed` | Yes  | Yes   |
| Custom list (`custom_list`)     | `list:<id>`                                               | Yes  | No    |

Status bucket writes can change an item's library status. Removing from a bucket removes the item from the SIMKL library and clears its rating.

Custom lists are read through SIMKL's custom list API, which is read-only and in beta:

* Listed only when the account type is PRO or VIP. Free accounts make no request and see no custom lists.
* A "premium only" answer from SIMKL is treated as an error, not as an empty list.
* Add and remove on a `list:` ID are refused locally and never sent, because SIMKL accepts such calls without performing them.
* Each list has one media type: movies, shows or anime.
* Lists are read in pages of 500, in SIMKL's order. The list's `updated_at` is used as the checkpoint.
* SIMKL's automatic recommendation lists appear as custom lists too.

### Endpoint lifecycle

Endpoint creation first discovers provider resources. It then stores the selected resource as an endpoint.

The picker can create, rename, or delete a provider playlist where supported.

Provider playlist creation differs from endpoint creation.

Provider playlist names support up to 20 characters. Endpoint, mapping, and ruleset names support 10.

Names must start with a letter or number. They must use supported safe characters.

#### Pending provider creation

`pending_create` stores a provider playlist name and media type before creation.

The runner can create that target before writing playlist items.

The UI normally creates provider playlists directly. Manual `pending_create` changes are rarely needed.

### Mapping and pair integration

Pairs store selected playlist mapping IDs here:

```
pairs[].features.playlists.mappings
```

When saved, a mapping is validated against endpoint providers and profiles.

For one-way pairs, the source matches the pair source. Targets match the pair target.

For two-way pairs, either pair orientation can match.

Incompatible mappings are skipped during pair resolution.

The sync action opens Interactive Sync for the assigned pair.

For ruleset configuration, see [Rulesets](/crosswatch/main-dashboard/navigation/playlists/rulesets.md).

### Runtime state and matching

Playlist state is separate from orchestrator state:

```
/config/.cw_state/playlists_state.json
```

Each scope is derived from mapping identity, ruleset, source, and destination information.

```
managed
updated_at
meta
last_result
```

`managed` determines which items `managed_only` may remove.

`last_result` holds the latest run of a mapping. A run that fails before it can read its lists stores a failed result with the error text, so it appears in the list of syncs and the Activity overview.

Changing the mapping topology changes the scope and may create a new baseline.

Playlist items use canonical keys, external IDs, and key overlap for cross-provider matching.

Stable external IDs improve matching reliability.

### Aggregate, partition, and capacity

Aggregate mode treats several playlist resources as one logical inventory.

Partition mode distributes managed items across target endpoints.

Advanced execution requires aggregate reads with partitioned writes.

`stable_first_fit` assigns items predictably. `track_assignments` preserves those placements.

`rebalance = never` avoids moving assigned items only to equalize targets.

`overflow = block` prevents silently exceeding logical capacity.

`per_endpoint_capacity` limits each target. `aggregate_capacity` limits all targets. `maximum_targets` limits target count.

These values are ruleset controls, not provider guarantees.

### Safety and execution

Large removal plans use the shared mass-delete guard.

The decision uses suspect thresholds and `allow_mass_delete`.

Verify both snapshots, profile selection, and baseline before allowing mass deletion.

Dry runs calculate additions, removals, and ordering without provider writes.

Use dry runs after changing topology or destructive rulesets.

Plans track source, target, resolved, unresolved, addition, removal, reorder, and warning counts.

Applied results are stored as `last_result` and shown in the UI.

Unresolved items do not always fail the entire run. They could not be safely written.

### Refresh and deletion

Endpoint refresh updates provider metadata and `last_synced`.

It does not reconcile a mapping.

Provider playlist management checks provider capabilities and resource protection flags.

Deleting an endpoint differs from deleting its provider playlist.

Deleting a mapping removes its configuration and pair reference. It never deletes provider playlists.

Stale state can be pruned after topology changes.

### Operational guidance

1. Validate the provider and profile before creating mappings.
2. Start with **Direct sync** and `managed_only`.
3. Prefer stable external IDs on both providers.
4. Run a dry run after ruleset or topology changes.
5. Review unresolved items before allowing stricter removals.
6. Use Mirror only when destination-only items should be removed.
7. Use aggregate and partition rulesets only for real capacity constraints.
8. Never manually edit `playlists_state.json` without understanding membership baselines.
9. Treat a published address like a password, and replace the key when it has been shared too widely.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://wiki.crosswatch.app/crosswatch/main-dashboard/navigation/playlists.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
