Your data .md

Up Next, tracked shows & change detection

You read a signed-in user's computed Up Next queue, manage which shows they track, and detect what changed since your last sync.

Up Next#

GET /v3/sync/up_next returns one entry per show the user has started or is currently watching, each carrying its next unwatched episode (when known) plus progress context. Unlike dropping a show from the site's own Up Next view, this endpoint always includes dropped shows and flags them with dropped: true instead of hiding them.

curl -H "Authorization: Bearer $TOKEN" \
  "https://flicklist.tv/api/v3/sync/up_next?limit=40"
[
  {
    "title": "Severance",
    "media_type": "tv",
    "status": "Returning Series",
    "ids": { "fldb": "flt_4b8e12d7", "tmdb": 95396, "imdb": "tt11280740", "tvdb": null, "slug": "severance", "anilist": null },
    "next_season_number": 2,
    "next_episode_number": 4,
    "next_air_date": "2026-06-01",
    "awaiting_next_episode": false,
    "episode_available": true,
    "progress_percent": 62.5,
    "dropped": false
  }
]

Drop a show with POST /v3/sync/up_next/drop, restore it with POST /v3/sync/up_next/undrop. Both take a single media identity, no batch, and neither touches watch history. Undrop 404s if the resolved show isn't currently dropped.

Tracked shows#

Tracking is independent of watchlisting or watching a show. It's purely "notify me, and surface this in my calendar and Up Next." GET /v3/sync/tracked returns every tracked show, most-recently-tracked first, with no pagination (a tracked list is small by nature).

POST /v3/sync/tracked tracks a single show and is idempotent, tracking an already-tracked show still returns 200. DELETE /v3/sync/tracked untracks it and 404s if the show wasn't tracked.

{ "tracked": true }

Change detection with last_activities#

GET /v3/sync/last_activities returns per-domain timestamps: movies and episodes each split into watched_at, paused_at, watchlisted_at, plus shows.watchlisted_at, lists.updated_at, and favorites. An overall all field is the max of everything, the single value to compare against a cached "last synced at." Every timestamp defaults to the Unix epoch when the user has no data in that category yet, it's never null, so there's always something to compare against.

curl -H "Authorization: Bearer $TOKEN" \
  "https://flicklist.tv/api/v3/sync/last_activities"
{
  "all": "2026-05-14T02:10:33.000Z",
  "movies": { "watched_at": "2026-05-14T02:10:33.000Z", "paused_at": "2026-05-01T00:00:00.000Z", "watchlisted_at": "2026-05-10T00:00:00.000Z" },
  "episodes": { "watched_at": "2026-05-13T20:00:00.000Z", "paused_at": "1970-01-01T00:00:00.000Z", "watchlisted_at": "1970-01-01T00:00:00.000Z" },
  "shows": { "watchlisted_at": "2026-05-09T00:00:00.000Z" },
  "lists": { "updated_at": "2026-05-14T02:10:33.000Z" },
  "favorites": "2026-04-20T00:00:00.000Z"
}

Poll-then-fetch pattern#

Store the all value locally after every sync. On your next poll, compare it and only refetch collections whose category timestamp advanced.

const last = await fetch('https://flicklist.tv/api/v3/sync/last_activities', {
  headers: { Authorization: `Bearer ${token}` },
}).then((r) => r.json());

if (last.episodes.watched_at > cachedTimestamps.episodesWatchedAt) {
  // refetch episode watch history
}
if (last.lists.updated_at > cachedTimestamps.listsUpdatedAt) {
  // refetch /sync/lists
}
cachedTimestamps = last;

This keeps a long-running integration well under the rate ceiling instead of re-pulling every collection on every poll.