Versions follow MAJOR.MINOR.PATCH (src/version.py); Apify shows MAJOR.MINOR from .actor/actor.json.
Every run logs its version and records it in the RUN_STATS key-value record.
- A run that returns nothing (every input bad, private, blocked or unreachable, or an empty input) now ends
SUCCEEDED with an empty dataset and the reason as its status message and in the log, instead of FAILED. Only an
unexpected error still fails the run.
RUN_STATS keeps the reason as before.
- No change to output fields or price.
- A run no longer fails when the store it remembers earlier runs in can't be opened (403: the account already has
a store of that name that this actor didn't create). It falls back to
humble-echidna-<name>, and if that is
refused too it runs without memory for that run. Users' existing memory is untouched: the usual name is tried first.
- Waits out longer
Retry-After answers: when a site or API asks it to wait before retrying, it now waits up
to 90 seconds (was 30), once per site, with at most 3 minutes of such long waits per run; a longer wait, or a
site that asks again after it was waited out, is reported with the reason instead of stalling the run.
- Narrower AI opt-out rule: a page is skipped as opting out of AI use only when the site's robots.txt
disallows it for a general AI token (Google-Extended, Applebot-Extended, CCBot, or OpenAI's, Anthropic's or
Perplexity's crawlers and user fetchers). Blocking only one company's crawler (Bytespider, Meta-ExternalAgent,
Amazonbot, Diffbot, Omgilibot, cohere-ai) no longer counts: GitHub and Notion pages, for two, are read now.
- No change to input, output or price.
- 2 ready-to-run examples published on Apify Store and linked from the README.
- Cheaper on paid Apify plans: $0.90 per 1,000 items on Starter, $0.80 on Scale and $0.70 on Business ($1.00 on the Free plan).
- Input field descriptions rewritten for AI agents (Apify's MCP server shows agents only the description, not the
form): each now states its default, its allowed range and how it combines with other fields. No change to field
names, types, defaults or behaviour.
- Internal: feed parsing, discovery and rendering now live in the shared
mms_feeds package, shared with the new article-extractor actor. No change in behaviour or output.
- Also honours robots.txt opt-outs aimed at AI crawlers (GPTBot, CCBot, ClaudeBot, ...), like page-to-markdown.
First release.
- Reads RSS 2.0 / 0.9x, RSS 1.0 (RDF), Atom 1.0 and JSON Feed 1.x from the URLs you give it; a website URL works
when its page advertises a feed with
<link rel="alternate"> (comment feeds last).
- One row per item: title, link, published/updated in ISO 8601 UTC, author name (email addresses removed),
summary and full text as plain text, optional Markdown, categories, enclosures, guid, feed title/URL/format.
- Filters: keywords (title, summary, full text, categories) and "published since" (date, date-time or a period).
- "Only new items": remembered per feed and per filter combination in the user's
rss-feed-reader-seen store;
items are marked seen only after they're written to the dataset, and a failed or empty fetch forgets nothing.
- The same feed given twice in one run is read and charged once.
- XML is parsed with defusedxml (no entity expansion, no external entities). Feeds up to 10 MB, 5,000 items per
feed, 100,000 characters per text field.
- Fetching through the shared client: robots.txt and Crawl-delay honoured, public addresses on ports 80/443 only.
- Charged per item returned, through Apify's standard
apify-default-dataset-item event.
- "Max results per run" input, and the maximum cost per run is honoured: once either is covered, feeds still
being fetched are cancelled and the rest are skipped (listed as
queriesSkipped in RUN_STATS).
- Failure isolation: a failing feed only affects itself.