> 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/providers/synchronization/adapter-jellyfin.md).

# Adapter: Jellyfin

Jellyfin adapter lets CrossWatch sync with your Jellyfin server. It supports watchlist, history, and progress. It prefers external IDs for matching.

### What it supports

* Direction: source or target in a pair (one-way or two-way)
* Features:
  * **Watchlist** (favorites, playlist, or collection mode)
  * **History** (played movies and episodes)
  * **Progress** (resume position)
  * **Playlists** (not supported yet)
* Indexing: present-state snapshot (reads “what exists now”)

{% hint style="info" %}
Connect Jellyfin first. Use: [Jellyfin (Authentication provider)](/crosswatch/providers/authentication/auth-media-servers/auth-jellyfin.md).
{% endhint %}

### How matching works

CrossWatch normalizes items into a common shape:

* `type`, `title`, `year`, `ids`
* Episodes can include `show_ids`, `season`, `episode`

IDs are pulled from Jellyfin `ProviderIds` when available (IMDb/TMDb/TVDb). For episodes, the adapter tries to include show context in `show_ids`.

{% hint style="warning" %}
Strict ID matching is the default.

If external IDs are missing, CrossWatch usually treats the item as a missing peer instead of guessing by title/year.

You can relax this per pair, but false positives get more likely, especially for episodes.
{% endhint %}

### Watchlist behavior

Pick one watchlist mode:

1. **Favorites** (default)\
   Uses the user `IsFavorite` flag for Movies and Series.
2. **Playlist**\
   Uses a playlist (default name: `Watchlist`) as the watchlist container.
3. **Collection**\
   Uses a named collection as the watchlist container.

Reads enumerate the chosen container. Writes toggle favorites or add/remove from the playlist/collection.

{% hint style="info" %}
Recommended: **Favorites** or **Collection**.
{% endhint %}

{% hint style="warning" %}
Jellyfin playlists can’t hold Series. Playlist mode will only cover Movies and Episodes.
{% endhint %}

### History behavior

* Reads played Movies and Episodes, sorted by `DateLastPlayed`.
* Each entry becomes a normalized event with `watched_at` in UTC (`...Z`).

{% hint style="info" %}
Jellyfin does not expose unique play-event IDs. CrossWatch approximates event identity using item key + timestamp.
{% endhint %}

### Progress behavior

* Read: current resume position (“Continue Watching”).
* Write: set resume position.
* Clear: supported (writes progress `0`).

Related: [Progress](/crosswatch/configure-pairs/features/progress.md).

### Settings (advanced)

The UI mirrors these under **Settings → Synchronization Providers → Pairs (with Jellyfin)**.

<details>

<summary>Important config keys</summary>

Watchlist:

* `mode`: `favorites` | `playlist` | `collection`
* `playlist_name`
* `watchlist_query_limit`, `watchlist_write_delay_ms`
* `watchlist_guid_priority`

History:

* `history_query_limit`, `history_write_delay_ms`
* `history_guid_priority`
* `history_libraries` (optional include-list of library IDs)

</details>

### Diagnostics

<details>

<summary>Health checks</summary>

* Ping: `GET /System/Ping`
* System info: `GET /System/Info`
* User probe: `GET /Users/{userId}`

Logs are prefixed with `[JELLYFIN:feature]` (example: `[JELLYFIN:history] ...`).

</details>

<details>

<summary>State and unresolved files</summary>

* History shadow (merge-only): managed by the module/orchestrator

These prevent infinite retries and make failures visible.

</details>

### Notes and limitations

* Missing external IDs reduces match quality.
* If writes are flaky, add a small write delay.
* Jellyfin actions are user-scoped. Use separate pairs per Jellyfin user.


---

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

```
GET https://wiki.crosswatch.app/crosswatch/providers/synchronization/adapter-jellyfin.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
