This score renders events from a self-hosted Jellyfin media server on the Tempo timeline: new media added to the library, playback start and stop, authentication failures, scheduled task results, and plugin changes. It is read-only. The actions open the Jellyfin web UI, an item’s detail page, or the admin dashboard in your browser, and copy the server URL or item ID. Nothing writes back to Jellyfin.

Jellyfin events on the Tempo timeline

How it works

Jellyfin has no native outbound notifications, but its official Webhook plugin does. The plugin watches server events and POSTs a JSON body to a destination you configure. Tempo’s ingestion server is a valid destination, so Jellyfin posts to Tempo directly. There is no relay and no Tempo-side helper for this score: the plugin is the only moving part you set up.

The score handles what happens once an event lands: the badge label, the severity, the grouping, the indicator emoji, and the action buttons. Severity comes from the event’s NotificationType (see the table below), and because the score sets senderSeverityWins, a severity that you put into the payload yourself overrides the score’s rule.

Setup

You need Tempo running with the Jellyfin score enabled, and administrator access to Jellyfin.

1. Enable the score and create a token

  1. In Tempo, open Manage Sources and enable Jellyfin. Built-in scores are activated there. Only the generic Scripts source auto-installs.
  2. In Settings → Ingestion, create a token bound to org.jellyfin and copy it.
  3. Note your Tempo ingest endpoint: http://<your-mac-ip>:7776/ingest. Use the LAN IP or hostname of the Mac that runs Tempo, since Jellyfin usually runs on a different machine.

2. Install the Webhook plugin

  1. In the Jellyfin web UI, open Dashboard → Plugins → Catalog.
  2. Find Webhook, install it.
  3. Restart the Jellyfin server when prompted (Dashboard → Restart).

3. Add a Generic Destination

  1. Open Dashboard → Plugins → Webhook.

  2. Click Add Generic Destination.

  3. Fill in the form:

    • Webhook Name: Tempo

    • Webhook URL: your ingest endpoint, for example http://192.168.1.10:7776/ingest. Keep Jellyfin on the plain port 7776. The plugin’s payloads are not compatible with Tempo’s TLS port 8776, where the request arrives with an empty body. This is a known limitation shared with the UniFi score. Playback and library events on a trusted LAN are fine over plain HTTP.

    • Notification Types: tick the events you want. A quiet, useful starting set is Item Added, Playback Start, Playback Stop, Authentication Failure, and Scheduled Task Failed.

    • Request Headers: add the Tempo token header.

      KeyValue
      X-Tempo-Tokenthe token from step 1
      Content-Typeapplication/json
    • Template: paste the body below. This is the part that carries the metadata keys the score reads. Without these keys the actions and grouping have nothing to work with.

      {
        "providerIdentifier": "org.jellyfin",
        "title": "{{#if Name}}{{Name}}{{else}}{{NotificationType}}{{/if}}",
        "eventType": "alert",
        "metadata": {
          "NotificationType": "{{NotificationType}}",
          "ItemId":     "{{ItemId}}",
          "ItemType":   "{{ItemType}}",
          "Name":       "{{Name}}",
          "SeriesName": "{{SeriesName}}",
          "Username":   "{{NotificationUsername}}",
          "DeviceName": "{{DeviceName}}",
          "ClientName": "{{ClientName}}",
          "ServerUrl":  "{{ServerUrl}}"
        }
      }
  4. Save.

Leave Playback Progress unticked. It fires roughly once a second during playback and floods the timeline.

4. Verify

Trigger one of the configured events, for example add a movie or fail a login. The event should appear in Tempo’s timeline within a couple of seconds, colored olive green, with the five default actions in the right panel.

What you’ll see

The score sets severity from the NotificationType field. Anything not listed falls through to the default Info.

Notification typeSeverityLabel
AuthenticationFailureerrorAuth failed
ApplicationErrorerrorError
*Failed (any)errorFailed
ScheduledTaskFailedwarningTask failed
PluginInstalledinfoPlugin
PluginUninstalledinfoPlugin
PluginUpdatedinfoPlugin
ItemAddedinfoNew item
PlaybackStartinfoStarted
PlaybackStopinfoStopped
(anything else)infoInfo

Playback start and stop events carry a subtitle built from the payload: ${Username} · ${DeviceName} (${ClientName}), so a row reads as who is watching, on what device, with which app.

Indicators

The score adds a small emoji in front of the row based on the item’s ItemType:

Other item types, such as episodes, carry no indicator.

Grouping

Two common floods collapse into single entries through the score’s grouping rules. The window is six hours.

Movies, authentication failures, and plugin events match none of these rules, so they render standalone, which is what you want for one-off events.

Actions

Five actions are attached to every event. All are read-only: they open a URL in your browser or copy a string.

ServerUrl and ItemId come straight from the payload, so an action that opens an item only works when the event carried an ItemId. The address must be reachable from your Mac. A LAN URL is fine, as is a Tailscale or VPN address. Tempo does not connect to it; it only builds the link for your browser to follow.

Metadata keys the score reads

Every key below comes from the template in step 3. Drop one and the matching behavior stops working.

Troubleshooting and limitations