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 }
]
}
itemhas the shape of its list (live-channels,vod-movies) or, for an episode, ofepisode-info.progressisposition / duration(0 to 1), ornullwhen 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
itemsbut still count intotal, so a page may come back shorter thanlimit. Keep paging withnext_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;itemis the episode that follows it (position0). 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>}.