The line's watch history lives in the panel, not in the app: every app signed in to the same line (yours, or any other app built on this API) sees it. Use it for "recently watched", "continue watching" and "recent channels". The panel cannot tell how far a movie was watched: the app reports it with history-update. Apps that use player_api.php do not write history.

History belongs to the line (there are no profiles). Signing out, logout-all or a password change do not erase it; history-clear does. The panel keeps the 300 most recent entries of each line, for 180 days.

POST history-update

Form-encoded body:

Field
type movie, episode or channel
id The item id (the episode id for an episode)
position Seconds from the start (movies and episodes; ignored for channels)
duration Total seconds, if known (0 or omitted: unknown; the panel keeps the last one it got)
watched Optional, 1 or 0. Without it, the item counts as watched once position reaches 95 % of duration

Answers {"stored": true}. position and duration go from 0 to 604800 (7 days); anything else is 400 invalid_parameter. Content outside the line's package is 403 not_in_package; an episode the panel cannot find, 404 not_found. Content in hidden categories is stored but not listed.

When to report (each report is a request to the panel; keep them few):

  • Movies and episodes: when playback pauses, stops or the app goes to the background, at the end (with watched=1), and every 2 minutes at most while playing. Never on every second or on seek.
  • Channels: once, after about 30 seconds on the channel. Never while zapping.
  • Starting a watched item again from the beginning makes it "in progress" again (unless you send watched=1).

The panel accepts 30 reports per minute per line, across all its devices. Beyond that it answers 429 rate_limited with Retry-After: drop that report, do not retry it; the next one replaces it.

GET history

Parameters: type (all default, movie, episode, channel), offset, limit (default 20, 1-50). Most recent first.

{
  "type": "all", "total": 2, "offset": 0, "limit": 20, "next_offset": null,
  "items": [
    { "item": { "id": 5001, "type": "episode", "season": 1, "episode_num": 1, "title": "Pilot", "…": "…",
                "series_id": 88, "series_name": "Breaking Bad", "series_poster": "https://img.example.com/bb.jpg" },
      "position": 1740, "duration": 3480, "progress": 0.5, "watched": false, "updated_at": 1767225000 },
    { "item": { "id": 4321, "type": "movie", "name": "The Matrix", "…": "…" },
      "position": 8160, "duration": 8160, "progress": 1, "watched": true, "updated_at": 1767220000 }
  ]
}
  • item has the shape of its list (live-channels, vod-movies) or, for an episode, of episode-info.
  • progress is position / duration (0 to 1), or null when the duration is unknown (and for channels).
  • Entries for content the line no longer has (removed from the panel or from its package) are left out of items but still count in total, so a page may come back shorter than limit. Keep paging with next_offset.

GET continue-watching

Parameter: limit (default 20, 1-50). What a "continue watching" row needs, most recent first, in the entry shape of history plus reason:

  • in_progress: a movie, or the latest episode of a series, started and not finished.
  • next_episode: the latest episode of a series was finished; item is the episode that follows it (position 0). A finished series does not appear.

One entry per series.

POST history-remove, POST history-clear

history-remove takes type and id and removes that entry; history-clear removes the line's whole history. Both answer {"removed": <number of entries>}.