Find YouTube creators by keyword or channel list. One lead row per channel: public e-mail and where it was found, website and social links, plus recent-video average and median views, like rate, upload frequency and sponsor signals. No login, no API key.
Builds 0.1.26 and 0.1.27 were test builds — 0.1.26 of the first half of these changes, 0.1.27 of all of them — used for the platform checks named below; they were not released. Build 0.1.28 is 0.1.27 with these two texts brought up to date.
No field of the input form changed, no output column was added or removed, no pricing change. What changes concerns a channel whose feed YouTube did not give — where an address is looked for, when such a channel is delivered, what the run says — and one rule for every channel: an address on a domain without mail servers no longer stops the search.
Addresses in video descriptions, without the feed. In two runs of 2026-10-07, 20 of 53 and 88 of 348 row e-mails had come from video descriptions, which the feed carries. Since 0.1.25 a row read from the uploads list had none of them. Now, when the channel itself shows no address that counts, the Actor opens video pages and reads their descriptions: of the channel's latest fifteen uploads, the two newest that run longer than three minutes (the list tells an upload's length; shorter ones when there are not two), and a third while an address was seen that does not count yet. The rule for such an address is the one for the feed's descriptions, applied to the pages read: in one page only, it counts when the words in front say it is the creator's own or its domain carries the channel's name; in two, it counts. An address under other uploads than the ones opened is not found, and one the feed's fifteen descriptions would make high can come out medium.
offline, on the 762 channels recorded on 2026-10-07 whose own description and links gave no usable address: 84 of the 106 row e-mails the feed's fifteen descriptions give were found again (another address in 3 cases), at 1.98 pages a channel; the newest two uploads of any length would have found 75. In that count a long video was one the feed does not mark as a Short;
live on 2026-10-08, in a local test run through a proxy, website look-ups off: 120 channels were read with their feeds, then again with the feed made to fail — 12 of the 15 row e-mails from video descriptions were found again and no other address was taken, at 1.92 pages for each of the 98 channels without an address of their own (188 pages); the other 105 rows carried the same e-mail, or none, in both; median views from the list were within ±10% of the feed's for 118 of 119 channels. (That run was made before the last changes of this build; none of them touches which pages are opened.)
on the platform, with the feed made to fail by the test switch (website look-ups off), twice — on build 0.1.26 and on build 0.1.27: the 60 channels a run had just found and read with their feeds were read again. Of the 16 row e-mails from video descriptions, 15 were found again (8 of 8, then 7 of 8): 11 as high and 4 as medium, where the feed had made all 16 high. The one that was missed stood in 8 of the feed's 15 descriptions and under neither of the two uploads opened; the 15 stood in 4 to 15. No other address was taken, and the other 52 rows of each run carried the same e-mail or none; median views from the list were within ±10% of the feed's for 59 of 59 and 58 of 59 channels. 94 and 95 pages for the 49 channels without an address of their own, no third page needed; 23.8 seconds against 6.2 and 25.0 against 5.6, memory peaks 170 and 152 MB of 1,024; with 256 MB, 30 channels in 14.0 and 23.4 seconds (peaks 141 and 128 MB); no request was refused or retried;
sponsorMentionsRecent, hasAffiliateLinks, promoCodes and domainsLinkedInRecentVideos stay as in 0.1.25 (null and empty): two or three descriptions do not stand for fifteen;
not measured: a real failure of the feed service with this build — the feeds had come back (all 40 we asked answered at 09:48 UTC) when it was built, and the test switch stands in for the feed's answer only — and a run that opens more than 188 video pages. YouTube limits video pages per address: our YouTube Channel Videos Scraper , which reads the same pages, measured roughly a thousand in a row before an address was refused for a while — some addresses much sooner — and about a page a second through Apify Proxy afterwards. The Actor moves the request to the proxy by itself; a page that still does not come is left out, and the run's status message now says how many pages could not be read.
A channel that gave neither its recent videos nor an e-mail is left for a later run. When neither the feed nor the uploads list answers, a row would hold neither of the two things a lead is paid for. Such a channel used to be delivered with empty columns and charged as a lead without e-mail; now it is not delivered, not charged, and a list (onlyNewChannels) does not remember it, so the list's next run can deliver it whole. A channel line you gave gets a free status row that names it; channels a keyword found are counted in the status message. A channel whose own description, links or website give an e-mail is delivered as before, with its recent-video columns empty, charged as a lead with e-mail and remembered by a list — so while both sources fail, a keyword run delivers only channels with an e-mail. A filter on recent videos (uploadedWithinDays, minMedianViews) leaves such a channel whether it shows an e-mail or not, as before. We have not seen both sources fail: in four platform runs of build 0.1.25 during the failure of 2026-10-08 the list was asked for 56 channels, and 55 rows came with its figures (the 56th, a channel that uploads Shorts only, was turned down by that run's own filter). With the feed and the list both made to fail by the test switch, on the platform (build 0.1.27; build 0.1.26 gave 7 and 13 on other channels, without the status rows, which came after it): of 20 channel lines, 6 were delivered for their e-mail and charged as leads with e-mail, and 14 were left for a later run, each with a free status row, none charged; with onlyWithEmail the same 14 were turned down for the reason below; a run of 8 channel lines without an address ended as failed with 8 status rows and no row charged; a keyword run with maxChannels: 5 delivered 5 channels with an e-mail after reading 26, and left 21.
An address on a domain without mail servers no longer stops the search. The Actor decided whether to open a channel's website — and now its video pages — by whether an address had been found that is not a low-confidence guess; whether its domain can receive mail was checked afterwards. A channel whose only such address was on a domain without mail servers ended with email: null and websiteScan: "not-needed". The check now comes first: such an address does not count, and the next place is looked at. In the saved runs of 2026-10-07 that concerned 2 of 1,000 rows and 1 of 100. With checkEmailDomains off nothing changes.
When a run that delivers nothing ends as failed. It did when more channels had been left for want of their recent videos than all filters together had turned down — so a search that brought many small channels could end as a normal run that advised loosening the filters while YouTube's feed was the reason. Now what the subscriber and country filters turned down is left out of the comparison: the run fails when, of the channels that passed those two, more were left than were turned down.
The status message. Channels YouTube did not give enough of are no filter's doing: they are no longer listed among "did not pass your filters" but counted apart — "N channels were left for a later run: YouTube's feed did not answer, and the uploads list did not give what is needed — their recent videos, or the figure a filter asks for. They are not charged, and a list does not remember them". A run that delivers nothing for that reason and fails says "Nothing delivered and no rows charged: YouTube's feed did not answer, and the uploads list did not give what is needed either."; one that does not fail ends with "Run it again later for the channels whose feed did not answer." The note about rows read from the uploads list now ends "…and an address in video descriptions was looked for in two or three of the latest uploads only"; the note about rows without figures now ends "…delivered for their e-mail, with the upload, view, like and sponsor columns empty (null)". New: "N video pages could not be read: an address that stands only in their descriptions is missing from the rows". A run that stops at its reading limit while channels were left says "too few of them could be delivered" where it said "the filters let too few through". The onlyWithEmail reason of 0.1.25 now reads "no public e-mail found (YouTube's feed did not answer: its video descriptions could not all be read)".
A test switch, for our own checks. What a run does while YouTube's feed fails could be checked on the platform only during a failure. A build that does not carry the tag latest now reads one more input value, debugFail (feed, uploads or both), that makes it treat the feed or the uploads list as unanswered without asking YouTube; such a run says "TEST RUN" in its log. A build tagged latest ignores it — and a build that loses that tag to a newer one honours it again when it is run by its number.
The fault of 2026-10-08 ended at some time between 06:47 UTC, when our last run with failing feeds ended, and 09:48, when all 40 feeds we asked for answered at the first request.
2026-10-08 — build 0.1.25
One output column was added: recentVideosSource. No input field changed, no column was removed, no pricing change. The values that change are those of a channel that has videos and whose feed YouTube did not give: its upload and view columns, null since 0.1.22, are now filled from the channel's uploads list.
Without the feed, the figures come from the channel's uploads list. YouTube's feed service fails for hours at a time: on 2026-10-08 it had begun by 01:25 UTC, and at 04:56 none of 40 feeds came in six tries each — a request from outside Apify got "not found" as well, and others have reported the same since December 2025. A channel's uploads list (its page "Uploads from …", one request) answered whenever we asked that morning (locally, through a proxy): for all 40 of those channels at 05:19, and in three local test runs of this Actor and the Channel Finder, where it was asked for 19, 54 and 185 channels, none had to be turned down for lack of it. It lists the channel's latest uploads of every kind, as the feed does, with YouTube's rounded views ("9.8M views") and their ages in words ("3 weeks ago") — and without likes, descriptions or exact times. So, for a channel whose feed does not come (after six requests, or two while the service is down for nearly every channel):
recentVideosAnalyzed, avgViewsRecent, medianViewsRecent, viewsPerSubscriber, daysSinceLastUpload, uploadsLast30Days, uploadsPerMonth, recentVideosSpanDays, latestVideo and topRecentVideo are read from that list, and the new column recentVideosSource says uploads list (feed in every other row that has recent videos);
against the feeds of the day before: median views within ±10% for 38 of the 40 channels; for the 33 channels with the same 15 uploads in both and ages in the list, uploads in the last 30 days the same for all 33, days since the last upload the same for the 10 that had uploaded within two weeks and within ±15 days for 24 of the 33; uploads per month within ±25% for 24 of the 31 for which both sources give one;
lastUploadAt, avgLikesRecent, likeRate, shortsShareRecent, sponsorMentionsRecent and hasAffiliateLinks stay null, promoCodes and domainsLinkedInRecentVideos stay empty, and no address can be looked for in video descriptions: the list does not carry what they need;
a channel that uploads Shorts only shows its list without ages (2 of the 40): its view columns are filled, its activity columns stay null;
uploadsPerMonth and recentVideosSpanDays are null when the newest and the oldest of the uploads are worded alike in weeks, months or years ("2 years ago"): no span is made up for them;
uploadedWithinDays and minMedianViews judge the channel by these figures; only a figure the list does not carry is turned down as "recent videos not known (YouTube's feed did not answer)";
when the list does not answer either, the row is as before: recentVideosAnalyzed: null, and recentVideosSource: null;
with onlyWithEmail, a channel for which no address was found while its video descriptions could not be read is turned down as "no public e-mail found (video descriptions not read: YouTube's feed did not answer)" — counted apart from "no public e-mail";
the status message counts both kinds of rows, and they are charged like any other row.
2026-10-08 — builds 0.1.20 to 0.1.24
Changes since the build that was published on 2026-10-07 (0.1.19). No input field or output column was added or removed, no pricing change. Three values changed for one case — a channel that has videos and whose feed YouTube did not give: recentVideosAnalyzed is now null (it was 0), sponsorMentionsRecent is null (it was 0) and hasAffiliateLinks is null (it was false).
When YouTube's feed fails, the Actor asks again and says what it could not read (0.1.22, 0.1.23). The recent-video figures, the addresses in video descriptions and the sponsor signals come from each channel's public feed. 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 channel in that state was delivered as if it had no uploads (recentVideosAnalyzed: 0), and a filter on recent videos turned it down as "no recent upload". Now:
a feed that does not come is asked up to five more times (that brought 25 of the 40 at 02:01 and 39 at 02:25);
(0.1.23) while the last channels of a run bring next to no feeds, a feed is asked one more time instead of five: at 02:58 UTC the service was down almost altogether — the same forty channels gave 2 feeds in six tries each, and twenty of them, asked from eight addresses, 13 feeds in 312 answers — and asking five more times only made a run slower;
a channel whose feed still does not come is delivered with recentVideosAnalyzed: null and its recent-video and sponsor columns empty — not known, instead of none — and the status message counts such rows;
uploadedWithinDays and minMedianViews turn such a channel down as "recent videos not known (YouTube's feed did not answer)"; when nothing could be delivered and most of the channels turned down were turned down for that reason, the run fails with that reason instead of advising you to loosen your filters (a run of a list that has delivered before does not fail for it);
a channel without public videos is unchanged: recentVideosAnalyzed: 0;
a row without its recent-video figures is charged like any other row, and an "only new" list remembers it like any other.
Wording of a run's last word (0.1.24). A run that delivers nothing used to say "nothing charged". The run-start event ($0.00005) 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.24): 18 statements were wrong or said more than the measurements do, 9 had no record behind them. Among them: the prefilled input takes 4 to 7 seconds of run time, not "4 to 5"; a single mention in a video description can become the row's e-mail when the words in front of it say it is the creator's own; the outage of YouTube's feed service began around 01:25 UTC, not after 01:30; a row without figures is charged, and running the channel again is charged again. The full list is in the Actor's QA record.
A channel is named even when its feed gives nothing. YouTube's feed answers 404 for some channels. A channel you gave by its ID, with nothing else to name it, then came with title: null; its own page names it now (one extra request for such a channel).
A run that delivers nothing says why in its dataset too. When every channel 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.
The Actor's title in Apify Store is now "YouTube Channel Email Scraper — Creator & Influencer Leads" (it was "YouTube Channel Email & Creator Leads Scraper"). Its address foxlabs/youtube-channel-email-scraper is 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.
A run of an "only new" list that is killed by its timeout was tested on this Actor on the platform: the list's next run read the killed run's rows back and delivered none of them again.
The record of an "only new" list no longer carries the mark that said whether the list's last run ended without being cut short; it never changed what this Actor delivers.
0.1 — 2026-10-07
First version.
Channels come from keywords (YouTube's channel search and the creators behind the top videos for the keyword) or from your own list of channel URLs, @handles and channel IDs.
A search is followed to the end of YouTube's results and then again, up to five times, while a pass still brings enough channels the earlier ones did not.
One lead row per channel: public e-mail with its source and confidence, website and social links, country, subscribers, total views.
Audience and activity figures from the channel's latest uploads (15 at most): average and median views, like rate, uploads per month, days since the last upload, share of Shorts, latest and best recent video.
Sponsorship signals from recent video descriptions: sponsor mentions, promo codes, affiliate links, and the brand domains linked (sub-domains counted as one brand; affiliate short links and public bodies left out).
website is the creator's own site as far as the channel's links tell: a link on a domain that carries the channel's name comes first, then a link titled as the website or blog; short links and affiliate links are never the website.
The website is read when YouTube shows no usable address; an address counts only on that site's own domain — or as a free mailbox (Gmail and the like) shown on that site — and is rated high only when the domain carries the channel's name. Only plainly written addresses are read: one that is encoded in the page source is left alone.
An address that appears in a single video description counts only when the words in front of it say it is the creator's own ("business inquiries: …", "e-mail me at …") or its domain carries the channel's name; anything else stays low and is never the row's e-mail.
Filters: subscriber range (a maximum of 0 means no upper limit), countries, recent upload, median views, only channels with an e-mail. Filtered channels are not delivered and not charged.
"Only new channels": a named list remembers delivered channels and later runs skip them.
Pay per delivered row: channel-lead-with-email when the row has a public e-mail, channel-lead otherwise. Status rows are free.
Rows are written in small batches; a row is charged when it is written, and the run's spending limit and maxChannels stay exact.
A keyword that brings nothing gets a free status row that says why; a run that stops at its limit says which keywords it did not get to.
A run the platform restarts or moves to another server continues from the rows it already delivered, without repeating or re-charging them.
No proxy to set up: requests go out directly; a kind of request YouTube refuses — or keeps leaving unanswered — is moved to Apify Proxy by the Actor itself, the others stay direct.
Channel lines: an @handle in any script, a channel's old custom address (youtube.com/name), and an @handle that YouTube answers with another address of the same channel all lead to the channel.
Rows are written in the order they were delivered, also when a run mixes the two events.
"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.
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.