Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/chrisbenincasa/tunarr/llms.txt

Use this file to discover all available pages before exploring further.

The Programming API covers everything related to content programs stored in Tunarr’s database and how they are arranged into channel lineups. You can search across all programs, look up individual items or groupings (shows, seasons, artists, albums), retrieve or replace a channel’s programming, and use Tunarr’s built-in scheduling tools to auto-generate a schedule from a time-slot or random-slot template.

Search Programs

Full-text and filtered search across all programs indexed by Tunarr’s search engine (Meilisearch).
POST /api/programs/search
Request body — a ProgramSearchRequest object:
query
string
Free-text search query.
filter
object
Structured filter object (genres, years, media source IDs, etc.).
offset
integer
Pagination offset. Default 0.
limit
integer
Maximum results. Default 25.
Response 200ProgramSearchResponse with matching programs plus facet data.
curl -X POST http://localhost:8000/api/programs/search \
  -H "Content-Type: application/json" \
  -d '{ "query": "jurassic", "limit": 10 }'

Get Program

Returns a single content program by its internal UUID, including season and show metadata for episodes, and album/artist metadata for tracks.
GET /api/programs/:id
id
string (uuid)
required
Program UUID.
Response 200TerminalProgram object:
uuid
string (uuid)
Program identifier.
type
string
movie | episode | track | music_video | other_video.
title
string
Program title.
duration
number
Duration in milliseconds.
sourceType
string
Origin media source type: plex | jellyfin | emby | local.
year
number
Release year (may be null).
show
object
Parent show (episodes only).
season
object
Parent season (episodes only).
album
object
Parent album (tracks only).
artist
object
Parent artist (tracks only).
Response 404 — program not found.
curl http://localhost:8000/api/programs/e7f8a9b0-0000-0000-0000-000000000005

Get Program by External ID

Looks up a program by its external sourceType|sourceId|itemId composite key. This is useful when you have a Plex or Jellyfin item key and need the Tunarr UUID.
GET /api/programming/:externalId
externalId
string
required
Pipe-delimited composite: {sourceType}|{mediaSourceId}|{externalKey}.
Example: plex|my-server|12345
Response 200TerminalProgram object. Response 400 — invalid source type. Response 404 — program not found.
curl "http://localhost:8000/api/programming/jellyfin%7Chome-jellyfin%7Ca1b2c3d4ef56"

Batch Lookup Programs by External IDs

Fetches multiple programs at once by their external IDs. Returns a map of uuid → program.
POST /api/programming/batch/lookup
externalIds
array of strings
required
List of pipe-delimited external ID strings: ["plex|server1|111", "jellyfin|server2|222"].
Response 200Record<string, TerminalProgram> keyed by program UUID.
curl -X POST http://localhost:8000/api/programming/batch/lookup \
  -H "Content-Type: application/json" \
  -d '{ "externalIds": ["plex|my-plex|12345", "jellyfin|home-jf|abc"] }'

Get Program Grouping

Returns a program grouping (show, season, music artist, or album) by its UUID, including nested children.
GET /api/program_groupings/:id
id
string (uuid)
required
Grouping UUID.
Response 200ProgramGrouping (show, season, artist, or album object). Response 404 — grouping not found.

Get Program Children

Returns the immediate children of a grouping: episodes for a season, tracks for an album, seasons for a show, or albums for an artist.
GET /api/programs/:id/children
id
string (uuid)
required
Grouping UUID (show, season, artist, or album).
offset
integer
Pagination offset.
limit
integer
Pagination limit.
channelId
string (uuid)
Optional: scope children to those used in a specific channel.
Response 200ProgramChildrenResult with total, size, and result: { type, programs }. Response 404 — grouping not found.

Get Program Descendants

Returns all leaf-level programs that belong to a grouping at any depth (e.g. all episodes in a show, all tracks in an artist).
GET /api/programs/:id/descendants
id
string (uuid)
required
Grouping or program UUID.
Response 200 — array of ContentProgram objects. Response 404 — not found.

Get Show

Returns a TV show grouping with its seasons (and optionally all episodes).
GET /api/programming/shows/:id
id
string (uuid)
required
Show UUID.
includeEpisodes
boolean
Include all episodes across all seasons. Default false.
Response 200 — show object with nested seasons[].

Get Show Seasons

Returns only the season groupings for a given show.
GET /api/programming/shows/:id/seasons
id
string (uuid)
required
Show UUID.
Response 200 — array of season objects.

Get Season

Returns a single season grouping.
GET /api/programming/seasons/:id
id
string (uuid)
required
Season UUID.
Response 200 — season object.

Get Channel Programming (Condensed)

Returns the condensed programming configuration for a channel, suitable for display in the channel editor.
GET /api/channels/:id/programming
id
string (uuid)
required
Channel UUID.
offset
integer
Pagination offset. Default 0.
limit
integer
Pagination limit. Pass -1 for all. Default -1.
Response 200CondensedChannelProgramming object. Response 404 — channel or lineup not found.
curl "http://localhost:8000/api/channels/a1b2c3d4-0000-0000-0000-000000000001/programming?offset=0&limit=50"

Update Channel Programming

Replaces the channel’s entire lineup. After updating, Tunarr regenerates the EPG guide automatically.
POST /api/channels/:id/programming
id
string (uuid)
required
Channel UUID.
Request bodyUpdateChannelProgrammingRequest:
type
string
required
Lineup type: "manual" for an explicit ordered list.
programs
array
required
Ordered array of program references. Each entry identifies a program in Tunarr’s database or a flex/filler slot.
Response 200 — updated CondensedChannelProgramming. Response 404 — channel not found. Response 500 — lineup update failed.
curl -X POST http://localhost:8000/api/channels/a1b2c3d4-0000-0000-0000-000000000001/programming \
  -H "Content-Type: application/json" \
  -d '{
    "type": "manual",
    "programs": [
      { "type": "content", "id": "e7f8a9b0-0000-0000-0000-000000000005" },
      { "type": "flex", "duration": 1800000 }
    ]
  }'

Apply Time-Slot Schedule

Generates a lineup from a time-slot schedule definition and previews (but does not save) the result. Use the response to review the generated schedule before saving it with Update Channel Programming.
POST /api/channels/:channelId/schedule-time-slots
channelId
string (uuid)
required
Channel UUID.
Request body:
schedule
object
required
A TimeSlotSchedule object:
  • type (string) — "time" (discriminator)
  • slots (array) — list of slot definitions, each with a startTime, order, and content source
  • period (string) — how often the schedule repeats: "day" | "week" | "month"
  • maxDays (integer) — how many days ahead to materialize
  • padStyle (string) — filler padding strategy
  • latenessMs (number) — lateness tolerance in milliseconds
Response 200TimeSlotScheduleWithPrograms — the generated lineup with materialized program objects. Response 400 — invalid slot configuration. Response 404 — channel not found.
curl -X POST \
  http://localhost:8000/api/channels/a1b2c3d4-0000-0000-0000-000000000001/schedule-time-slots \
  -H "Content-Type: application/json" \
  -d '{
    "schedule": {
      "type": "time",
      "period": "day",
      "maxDays": 30,
      "latenessMs": 0,
      "padStyle": "next",
      "slots": [
        {
          "startTime": 72000000,
          "order": "next",
          "showId": "show-uuid-here",
          "type": "show"
        }
      ]
    }
  }'

Apply Random-Slot Schedule

Generates a lineup from a random-slot schedule (content is randomly ordered within configurable time windows).
POST /api/channels/:channelId/schedule-slots
channelId
string (uuid)
required
Channel UUID.
Request body:
schedule
object
required
A RandomSlotSchedule object:
  • type (string) — "random" (discriminator)
  • slots (array) — slot definitions specifying content sources and durations
  • period (string) — "day" | "week" | "month"
  • maxDays (integer) — how many days ahead to materialize
  • padStyle (string) — filler padding strategy
Response 200SlotScheduleWithPrograms — the generated lineup with materialized program objects. Response 400 — invalid slot configuration. Response 404 — channel not found.

Get Channel Schedule

Returns the currently persisted (materialized) schedule for a channel, if one exists.
GET /api/channels/:id/schedule
id
string (uuid)
required
Channel UUID.
Response 200{ "schedule": MaterializedSchedule | undefined }.
curl http://localhost:8000/api/channels/a1b2c3d4-0000-0000-0000-000000000001/schedule

Get Facet Values

Returns the distinct values (and their counts) for a given facet field across all indexed programs.
GET /api/programs/facets/:facetName
POST /api/programs/facets/:facetName
facetName
string
required
The field to facet on (e.g. "genre", "year", "studio").
facetQuery
string
Filter facet values to those containing this string.
mediaSourceId
string (uuid)
Scope facets to programs from a specific media source.
libraryId
string (uuid)
Scope facets to programs from a specific library.
Request body (POST only):
filter
object
Structured filter to apply before computing facets.
Response 200{ "facetValues": Record<string, number> }.

Build docs developers (and LLMs) love