> 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

Use **Playlists** to connect provider playlists and collections through explicit mappings.

{% tabs %}
{% tab title="End users" %}
Create and synchronize named playlists between supported CrossWatch providers.

Playlists differ from **Watchlist**. Watchlist sync manages a provider's standard plan-to-watch list.

Use Playlists for named lists you choose, such as Plex playlists or Trakt lists.

Open **Main Dashboard → Playlists**.

Start with one source, one destination, and the **Direct sync** ruleset.

### 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 playlist. A playlist may be read-only.

Some playlists can be created, renamed, deleted, reordered, or edited.

{% hint style="warning" %}
SIMKL uses built-in status buckets as playlist endpoints. SIMKL Custom Lists are unsupported.

Changing an endpoint can move or remove items from your SIMKL library.
{% endhint %}

### How Playlists is organized

#### Playlist endpoints

An endpoint connects CrossWatch to one playlist on one provider profile.

It records the provider, profile, and selected provider playlist.

The endpoint list shows its name, playlist type, status, last refresh, and actions.

Treat an endpoint as a reusable reference to a provider playlist.

#### Mappings

A mapping connects one source endpoint to a destination endpoint.

It defines how playlist items move between those endpoints.

The mapping list shows its source, destination, ruleset, sync pair, status, and latest result.

#### Activity overview

Activity overview shows recent playlist runs, their changes, and their status.

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

### Create an endpoint

1. Select **New endpoint**.
2. Choose the provider and profile.
3. Select the provider playlist.
4. Change the generated endpoint name if needed.
5. Save the endpoint.

Use the search field when a provider has many playlists.

The playlist picker may also offer create, rename, or delete actions.

Those actions change the real provider playlist.

### Create a mapping

1. Select **New mapping**.
2. Choose the source endpoint.
3. Choose a different destination endpoint.
4. Select a ruleset.
5. 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.

### Run and review a sync

Use the mapping's sync action to run that mapping.

CrossWatch blocks conflicting playlist runs while synchronization is active.

Check the mapping result and Activity overview after every run.

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

### Refresh or edit an endpoint

Refresh reloads provider metadata and updates the endpoint status.

It does not run the playlist mapping.

Refresh an endpoint after renaming, changing, or recreating its provider playlist.

Edit an endpoint to change its name or selected provider playlist.

### Delete safely

Check mappings before deleting an endpoint. Mappings can use it as a source or destination.

Deleting an endpoint removes only its CrossWatch reference.

Deleting a provider playlist removes the real playlist from that provider.

Deleting a mapping removes its configuration. It does not delete either provider playlist.

### Membership behavior

#### Add only

Adds missing source items to the destination.

It does not remove destination items.

Use it when you also manage destination items manually.

#### Managed only

Adds missing source items and removes items CrossWatch previously managed.

It leaves destination-only items unchanged.

This is the normal **Direct sync** behavior.

#### Mirror

Makes destination membership match the source.

It can remove destination items absent from the source.

Use Mirror only when the source fully controls the destination.

### Playlist order

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

If reordering is unsupported, CrossWatch reports a warning.

### Smart and special lists

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

CrossWatch only enables actions that the provider and playlist support.

### Recommended first setup

1. Create one source endpoint.
2. Create one destination endpoint.
3. Create one mapping with **Direct sync**.
4. Run the mapping manually.
5. Review the result and activity.

Use Mirror or advanced rulesets only after this setup works as expected.

### Troubleshooting

#### Provider is unavailable

Confirm the provider is configured in **Connections** and supports playlists.

#### Playlist is missing

Refresh the picker and confirm the selected provider profile.

Some list types are not available as playlist resources.

#### Rename or delete is unavailable

The provider or selected playlist does not support that operation.

#### Mapping does not run

Confirm both endpoints exist and match the associated sync pair.

Also check whether another synchronization is active.

#### Items are unresolved

Unresolved items usually need better matching data.

Use stable external IDs where possible. Check **Analyzer** when failures persist.
{% endtab %}

{% tab title="Power users" %}

### Technical reference

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

Open **Main Dashboard → Playlists** to manage them through the UI.

### 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.

### 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 Custom Lists are unsupported.

SIMKL endpoints represent built-in status buckets. Writes can change an item's library status.

Do not treat SIMKL endpoints as independent custom playlists.

### 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.

### Ruleset schema

The current ruleset schema version is `1`.

```
direction: one_way | bidirectional
initial_sync: source_authoritative
read_mode: direct | aggregate
write_mode: direct | partition
membership: add_only | managed_only | mirror
order: ignore | preserve
deduplicate: canonical_id
allocation: stable_first_fit
rebalance: never
overflow: block
```

Numeric fields:

```
per_endpoint_capacity
aggregate_capacity
maximum_targets
```

`track_assignments` controls stable item placement between runs.

#### UI presets

* **Direct sync** — one-way, direct, managed membership, unordered, one target.
* **Mirror source** — one-way, direct, mirrored membership, preserved order.
* **Split large playlists** — partitioned writes with capacity and stable assignments.
* **Merge playlists** — aggregate reads with direct writes.
* **Limited account sharing** — bidirectional aggregate reads and partitioned writes.
* **Custom** — exposes detailed ruleset fields.

#### Built-in TraktFree ruleset

`TraktFree` uses:

```
direction = bidirectional
initial_sync = source_authoritative
read_mode = aggregate
write_mode = partition
membership = managed_only
order = ignore
deduplicate = canonical_id
allocation = stable_first_fit
rebalance = never
overflow = block
per_endpoint_capacity = 250
aggregate_capacity = 1000
maximum_targets = 5
track_assignments = true
```

These capacities describe CrossWatch configuration. They do not guarantee provider plan limits.

### Membership and ordering

`add_only` plans additions only. It never removes destination items.

`managed_only` removes only destination items previously recorded as CrossWatch-managed.

`mirror` can remove every destination item absent from the source snapshot.

Use Mirror only when the source controls the complete destination membership.

`ignore` synchronizes membership without ordering. `preserve` calculates and applies target ordering.

Mappings reject `preserve` when a destination is known to be unordered.

### 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.

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.

### Troubleshooting

#### Mapping is not attached to a pair

Confirm the source matches one pair side. Confirm targets match the opposite side.

#### Mapping is skipped

Check whether it is disabled, incomplete, or incompatible with the pair.

#### Managed items remain

`managed_only` removes only items in the stored `managed` baseline.

Topology changes can select a different scope and baseline.

#### Unexpected removals

Check membership mode first. `mirror` intentionally reconciles all destination membership.

Verify source and destination snapshots before allowing a large deletion.

#### Order is not preserved

Confirm that the destination reports `can_reorder`.

Some provider endpoint types are intentionally unordered.

#### Playlist actions are missing

The resource is protected, or the provider lacks the required capability.
{% endtab %}
{% endtabs %}


---

# 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
