# Changelog of YouTube Channel Videos Scraper — Exact Stats & Outliers (`foxlabs/youtube-channel-videos-scraper`) Actor

- **URL**: https://apify.com/foxlabs/youtube-channel-videos-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/foxlabs/youtube-channel-videos-scraper.md

## Changelog

### 2026-10-08 — build 0.1.17

README only; no code, input field, output column or pricing change.

- The README's answer to "why can it be empty for a channel's latest videos too?" said of the failure of YouTube's feed service on 2026-10-08 "still at our last reading at 03:21". By the run records of this series of Actors the failure ended at some time between 06:47 UTC, when the last run with failing feeds ended, and 09:48, when all 40 feeds we asked for answered at the first request. The answer now says so, and that others describe the same fault of this endpoint as recurring since December 2025 (threads at n8n and Google's developer forum, an issue at Miniflux, a pull request at RSS-Bridge) — something our source research for these Actors had not found.

### 2026-10-08 — builds 0.1.14 to 0.1.16

Changes since the build that was published on 2026-10-07 (0.1.13). No input field or output column changed, no pricing change.

- **A feed that does not come is asked again, and a "not found" from it is no longer taken at its word (0.1.16).** The time of day of a channel's latest 15 uploads comes from the channel's public feed — and so do their description with `details: "figures"` or `"list"`, and their unrounded views and likes with `"list"`. On 2026-10-08 — by our run records from about 01:25 UTC, and still at our last reading at 03:21 — YouTube's feed service answered "not found" or "server error" for channels that have a feed: of 40 feeds that had answered the day before, 8 answered a single request at 02:01 UTC and 14 at 02:25. Until this build a "not found" was read as "this channel has no feed", so the rows came without those values and without a word about it. Now the feed of a channel that has videos is asked up to five more times (that brought 25 of the 40 at 02:01 and 39 at 02:25; while a run's last channels bring next to no feeds — at 02:58 the service was down almost altogether — it is asked once more instead of five times), and when it still does not come the status message says "The feed of N channels did not answer: their latest uploads come without …", naming what is missing at the run's `details` level — the time of day; with `figures` the description too; with `list` also the likes, the date of an upload older than a day, and the unrounded view counts. (When the feed gave no answer at all the message already said so, but named only the time of day.)

- **Wording of a run's last word (0.1.16).** A run that delivers nothing used to say "nothing charged". The run-start event is charged for every run, so the message now says "no rows charged". Nothing about charging itself changed.

- **README corrected after an independent fact-check (0.1.16):** 20 statements were wrong or said more than the measurements do, 10 had no record behind them. Among them: a live stream that the channel's feed lists does carry a view count; with `details: "list"` an upload under a day old is dated from the list; a fresh upload can keep the list's rounded view count although it is in the feed; the restarted test run had 92 rows, not 76, when it was restarted; "10,000 channels a run" is the input limit, not a measured run. The full list is in the Actor's QA record.

- **A run that delivers nothing says why in its dataset too.** When every video was filtered out, a run used to end with an empty dataset and the reason in its status message only. It now also writes one free status row with that message, as the comments and search Actors of this series do, so a call that reads only the dataset is not left with an empty answer. An "only new" run that finds nothing new still leaves the dataset empty.

- **A killed run of an "only new" list is made up for.** A run that is killed (a timeout, the memory limit) cannot save the last videos it delivered. The list's next run now reads them back from that run's dataset before it starts, so they are not delivered a second time. The four sibling Actors already did this; this build brings it here.

- `commentsOff` is described more exactly: it is `true` when the video's page shows no comment section — comments are turned off, or the video is for members only. (The README used to name "a stream in progress" as a reason; a stream on air has a comment section unless its owner turned comments off.) The values are the same.

- README rebuilt in the foXLabs layout: use with AI agents (Apify MCP server, agentic payments), getting started, use cases, integration, a price table, legal notes. The measured figures are the ones of 2026-10-07.

### 0.1 — 2026-10-07

First version.

- A channel's Videos, Shorts and Live lists, followed to their end, in the channel page's own orders: latest, most popular, oldest. A channel with only a few videos, which shows no sort options, has its short list put in order by the Actor.
- Three levels of detail per video (`details`):
  - `figures` (the default) — what a video's page keeps refreshing: unrounded views, likes and the publish date (one small request per video);
  - `full` — the video's own page: the same, plus the number of comments, the description, hashtags and chapters (one large request per video; slower);
  - `list` — the channel's list and feed alone: the latest 15 uploads still come with unrounded views and likes and the publish time to the second; older videos with the list's rounded figures. `viewsAreExact` says which.
- When YouTube stops answering for video pages, videos are not left out: they come with their exact figures (`detailLevel: "figures"`), and the status message says how many.
- Outlier score: a video's views against the median of the channel's latest videos of the same kind.
- Filters: published within N days, minimum views, minimum outlier score. A video the list already rules out is dropped without a request; with the latest-first order a list is not read past the date limit (streams that are live or have not started do not count toward it).
- "Published within N days" delivers a video only when its age is known: with `details: "list"` a video the list shows no date for (a Short outside the feed, a stream on air) is left out and counted in the status message; streams and premieres that have not started are left out at every level.
- With `details: "list"`, `views` is the larger of the feed's unrounded count (which can lag) and the list's figure; a list figure below 1,000 counts as exact.
- A list is followed until YouTube offers no further page (no page limit). A list that stops answering part-way is reported in the status message, not passed off as complete.
- A channel whose feed does not answer is read all the same (its latest uploads then come without the time of day), and the status message says so.
- Channel lines: IDs, @handles in any script, `/channel/`, `/c/`, `/user/` and old `youtube.com/name` addresses. An @handle that YouTube answers with another address of the same channel is followed to the channel. A channel is called non-existent only when YouTube answers "not found"; any other refusal is reported as "could not be read".
- Description links: every link as a full address; a link to a moment in another video keeps its start time.
- With `details: "full"`, a video nobody has liked yet has `likes: 0`, and a video nobody has commented on has `commentsCount: 0` (both read `null`); `null` is kept for channels that hide their like counts and for videos whose comments are turned off.
- Live lists: a stream that is live comes with its audience (`liveViewers`) and, from the feed, its views so far; a stream or premiere that has not started is marked `isUpcoming` and carries no publish date and no views; a finished stream is marked `wasLive`. Members-only videos and Shorts are marked `isMembersOnly`.
- Rows come in the order of the channel's list.
- "Only new videos": a named list remembers delivered videos and later runs skip them.
- "Only new videos" looks at the top of each list (the first `maxVideosPerChannel`) and delivers what is new there; it does not walk back into the archive.
- Pay per delivered row, by its level of detail: `video-detailed`, `video-exact` or `video`. Status rows are free.
- A line that is not a channel, or a channel without videos of the kinds asked for, gets a free status row that says why.
- A run the platform restarts continues from the rows it already delivered.
- No proxy to set up: requests go out directly; a kind of request YouTube refuses is moved to Apify Proxy by the Actor itself, the others stay direct. A single request that gets no answer twice tries the proxy on its own; its kind moves only when that keeps happening.
- Rows are written in the order they were delivered, also in a run that mixes levels of detail.
- "Only new" lists and restarts: the rows a run wrote before the platform restarted it are taken into the list when the run continues, so the list's next run does not deliver them a second time.
- A write of the list that fails no longer ends the run: it is made up for with the next rows and at the end of the run, and if the list still cannot be saved the status message says so. A list that has reached its size says in the status message how many of its oldest entries it let go.
- `listName` takes letters, digits and hyphens (a hyphen not first or last; capitals are read as lower case). A name with "\_" or a hyphen at its end used to pass the input check and then fail the run at Apify's storage; it is now refused before the run starts.
- A run the platform restarts does not write a status row a second time for a search or line it had already found empty.
- `publishedDate` of a video less than a day old is given only when the hour YouTube names ("7 hours ago" is 7 to 8 hours) lies within one UTC day; when that hour holds midnight the field is `null` instead of the later of the two days. `daysSincePublished` is 0 for such a video.
- Ages read from "1 month ago" / "2 years ago" get bounds that hold whether YouTube counts 30-day or calendar months (28 to 61 days, 730 to 1,097): a video is ruled out by its list text only when it is certainly too old.
- `chaptersAutoGenerated` (`details: "full"`): `false` when the chapters are the creator's own, `true` when YouTube generated them for a video whose creator set none, `null` when the page does not say or the video has no chapters.
- A run of an "only new" list that is killed (a timeout, the memory limit) cannot save the last rows it delivered. The list's next run now reads them back from that run's dataset before it starts, so they are not delivered a second time.
