RSS Keyword Monitor — Only New Items & Webhooks avatar

RSS Keyword Monitor — Only New Items & Webhooks

Pricing

from $2.00 / 1,000 new items

Go to Apify Store
RSS Keyword Monitor — Only New Items & Webhooks

RSS Keyword Monitor — Only New Items & Webhooks

Monitor any RSS/Atom feeds for keywords on a schedule. Delivers & charges only new items since the last run. Webhooks, regex, n8n/Make/MCP ready.

Pricing

from $2.00 / 1,000 new items

Rating

0.0

(0)

Developer

Telemark Digital

Telemark Digital

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

0

Monthly active users

3 days ago

Last modified

Share

If you're re-parsing the same RSS feeds on a schedule and deduping downstream, this is your bill cut. RSS Keyword Monitor watches any RSS / Atom / RDF feeds, filters by your keywords or regex, and delivers only the new items it has never sent you before — with a webhook when something new lands. Most polls return nothing new and cost almost nothing, because unchanged feeds are skipped with conditional GET (HTTP 304). Built for pipelines and AI agents, not for reading in a browser.

What RSS Keyword Monitor does

Give it a list of feed URLs and (optionally) keywords, regex patterns, and exclude terms. Run it on an Apify Schedule — hourly, every 15 minutes, daily, whatever. On each run it:

  • fetches every feed (sending If-None-Match / If-Modified-Since, so unchanged feeds return 304 and cost nothing),
  • parses RSS 2.0, Atom 1.0 and RSS 1.0 (RDF), handling legacy encodings and broken feeds without crashing,
  • keeps a durable per-Task seen-set, so it suppresses repeat delivery within your configured dedup window,
  • filters by keyword / regex, drops your exclude terms, and
  • writes one clean JSON record per new item to the dataset — and only charges for those new items.

It turns a schedule (or an AI agent poll) into a cheap, recurring "what's new in my feeds" event stream. You can download the results as JSON, CSV, Excel or HTML, pull them from the API, wire them into n8n / Make / Zapier, or call it as an MCP tool.

When to use it — and when NOT to (please read this)

This Actor is honest about where it wins. Use it when you have specific feeds + filtering + cross-run dedup + one batched machine-readable call. Don't use it for these three cases — we'll tell you the better tool:

  • One-off bulk reads of a feed? Use a plain feed reader (e.g. automation-lab/rss-feed-reader). It's cheaper per item for a single full dump. We're built for the recurring delta, not the archive pull — and on a one-shot read we're honestly ~2× more expensive per item.
  • Watching just 1–3 feeds, unfiltered? A free n8n RSS Feed Trigger (self-hosted) or Make "Watch RSS feed items" will do it. We start paying off when you have many feeds, keyword/regex filtering, and want cross-run dedup state without wiring up custom code.
  • A human reading keyword alerts in an inbox? Inoreader Pro (~€6.67/mo, 2,500 feeds, 30 alert rules) or Feedly beat us for eyeballs. We are not an inbox — no reading UI, no ≤1h "refresh." We emit structured per-item JSON deltas for machines.

Still here? Then you're the buyer: an automation operator or agent feeding a pipeline, not an inbox.

How much does it cost?

Two events: $0.005 per run (actor-start) and $0.002 per new matching item (new-item, i.e. $2.00 per 1,000 new items). You are charged only for new items after filtering — duplicates, excluded items, unchanged (304) feeds and failed feeds are never billed. A quiet hourly watch is dominated by the tiny per-run fee, and most of those runs find nothing new.

Your workloadThis ActorA stateless reader charging per item every pollYou save
20 feeds, hourly, ~2 new matching/run720 × ($0.005 + 2×$0.002) = $6.48/mo720 × ($0.035 + ~200×$0.001) = $169/mo~26×
Same, their most defensive 1-item config720 × $0.055 = $39.60/mo (misses bursts)~6×
20 feeds, daily digest, ~40 new/day30 × ($0.005 + 40×$0.002) = $2.55/mo30 × $0.235 = $7.05/mo~2.8×
One-shot bulk read, 10 feeds × 50 items$0.005 + 500×$0.002 = $1.01$0.035 + 500×$0.001 = $0.54they win ~1.9× — use them
vs Make native, 50 feeds @ 15-min2,880 × $0.005 + items ≈ $15–20/mo~144k ops/mo ≈ $30+/mo tier, no keyword filter~2× + filtering

The wedge is the per-run fee and the fact that scheduled watches are mostly duplicates — which you shouldn't pay to receive again. On a hot, always-changing firehose (every item is new), the per-item price dominates and a plain reader is cheaper; if that's you, use one.

Only users on a paid Apify plan are billed; the free tier's monthly credit lets you trial it. Prices can change with 14 days' notice (Apify policy).

2-minute quickstart

  1. Click Try for free.
  2. In Feed URLs, paste one or more feeds (defaults are prefilled so you can just hit Start).
  3. Optionally add Keywords (e.g. acquisition, funding round) — leave empty to get every new item.
  4. Click Start. The first run seeds the seen-set and returns matching items (up to Max items per run).
  5. Run it again — you'll get 0 new items (everything's already been delivered). That's the point.

Run it on a schedule (the whole point)

Cross-run dedup only makes sense on a Task + Schedule, because state is keyed by Task.

  1. Configure the input, then Create task ▸.
  2. Open the Task ▸ Schedule ▸ e.g. every hour.
  3. Add a Webhook URL (below) to get pushed only when there's something new.

Example Task input:

{
"feeds": [
"https://hnrss.org/frontpage",
"https://www.theverge.com/rss/index.xml",
"https://feeds.bbci.co.uk/news/rss.xml"
],
"keywords": ["acquisition", "funding round", "layoffs"],
"excludeTerms": ["rumor"],
"matchFields": ["title", "description"],
"onlyNew": true,
"webhookUrl": "https://your-endpoint.example.com/rss-hook"
}

Recipes

n8n

Replace N "RSS Feed Trigger" nodes + N "Filter" nodes with one node. Add an HTTP Request node (or the Apify node) that runs this Actor, or add a Webhook node and paste its URL into webhookUrl — you'll receive a POST only when there are new items. Self-hosted n8n users watching 1–3 feeds don't need us; 50-feed graphs do.

Make (Integromat)

Every Make scenario poll consumes operations even when nothing is new — a 50-feed 15-minute watch burns ~144k ops/mo before any processing, and the native RSS module has no keyword filter. Instead: one Apify run polls all feeds and returns only filtered deltas to a single Custom webhook module. Point webhookUrl at that module's URL.

Slack (or Discord / Teams)

Create an Incoming Webhook in Slack and put its URL in webhookUrl. Slack endpoints receive a concise text message with up to 10 item links. Other endpoints receive the raw JSON payload below.

Raw webhook payload

webhookUrl receives a POST (Content-Type: application/json) only when there are new items:

{
"summary": {
"newItemsDelivered": 2,
"feedsOk": 8,
"feedsNotModified": 20,
"feedsError": 0,
"onlyNew": true,
"chargeLimitReached": false,
"webhookDelivered": true,
"charge": { "actorStart": 1, "newItemEvents": 2 }
},
"items": [
{
"feedUrl": "…",
"title": "…",
"link": "…",
"matchedTerms": ["acquisition"],
"firstSeenAt": "…",
"isNew": true
}
],
"itemsTruncated": false
}

items carries up to the 50 newest records; the full set is always in the dataset. A webhook failure is logged but never fails the run.

Use it from an AI agent (MCP)

Eligible paid Apify Actors can be exposed through mcp.apify.com when you add them to your MCP server configuration. The only-new semantics fit agent polling — "what's new in these feeds since I last asked?" Call this Actor with feeds + keywords; on a Task it remembers what it already returned within the dedup window.

Input

FieldTypeDefaultNotes
feedsstring[]Apify blog + BBC samplesRSS/Atom/RDF URLs, 1–500. Replace the samples with the feeds you want to monitor.
keywordsstring[][]Case-insensitive substrings, OR-matched. Empty = deliver every new item.
regexPatternsstring[][]OR-matched with keywords (case-insensitive). Invalid pattern fails the run with a clear error.
excludeTermsstring[][]Drop matched items containing any of these. Applied before charging.
matchFieldsstring[]["title","description"]Any of title, description, content, categories.
onlyNewbooleantrueOff = plain filtered read of the current feeds (still charged per item).
maxItemsPerRuninteger200Hard billing ceiling. In only-new mode, validators are held so overflow is retried on the next run.
dedupWindowinteger45Days an item stays in the seen-set (7–365).
includeContentbooleantrueInclude content:encoded HTML per item when present. No article-page fetching.
webhookUrlstringPOSTed only when there are new items.
resetStatebooleanfalseWipe this Task's seen-set + HTTP validators. Use once, then turn off.

Output

One dataset record per new matching item:

{
"feedUrl": "https://hnrss.org/frontpage",
"feedTitle": "Hacker News: Front Page",
"feedType": "rss",
"itemKey": "guid:https://news.ycombinator.com/item?id=44861023",
"guid": "https://news.ycombinator.com/item?id=44861023",
"title": "EU AI Act enforcement begins for foundation models",
"link": "https://example.com/eu-ai-act",
"author": "tosh",
"publishedAt": "2026-07-11T08:14:02.000Z",
"firstSeenAt": "2026-07-11T08:30:11.412Z",
"categories": ["ai", "regulation"],
"description": "Enforcement of the EU AI Act's obligations…",
"content": "<p>Full content:encoded HTML when the feed provides it…</p>",
"matchedTerms": ["eu ai act"],
"isNew": true
}

A per-run summary (per-feed statuses, counts, charge totals, and spending-limit status) is written to the run's key-value store under OUTPUT — the dataset stays clean for pipelines. firstSeenAt is our server clock at first delivery. publishedAt is the feed's untrusted claim: it is never used as a time cursor, but it is part of the hash fallback when an item has neither GUID nor link.

How the "only new" state works

  • Keyed by Task. State lives under your Task ID, so editing keywords or feeds never resets history — no fragile manual snapshot key to fat-finger. Ad-hoc (non-Task) runs share a persistent per-user scope; create a Task for isolated recurring monitoring.
  • Sharded per feed in a named key-value store, pruned on writes, capped at 20,000 identity keys/feed (oldest evicted). GUID items can use two keys. Eviction degrades to occasional re-delivery, not failure.
  • dedupWindow controls how long an item is remembered. Feeds that legitimately re-surface an item older than the window will re-deliver it.
  • Redirects: we follow up to 5; on a permanent (301) redirect we log the new URL and recommend you update it — state stays on the URL you configured, so renaming never orphans history.
  • resetState: true fully wipes this Task's seen-set and stored validators for a clean start.

Feed handling & reliability

  • Formats: RSS 2.0, Atom 1.0, RSS 1.0 (RDF). (JSON Feed is not yet supported — it returns a clear per-feed error, not a crash.)
  • Encodings: respects the Content-Type / XML-declaration charset with an iconv fallback for legacy JP/CN encodings; strips BOMs; tolerates leading whitespace; detects HTML error pages instead of choking on them.
  • Per-feed isolation: each network attempt has a hard timeout and every response has a 10 MB cap; one dead, hostile or malformed feed becomes a single error row in the summary — the run still succeeds and you're not billed for it.
  • Politeness: a descriptive User-Agent, gzip accepted, conditional GET on delta polls, bounded retries, and sequential requests for feeds configured on the same host. Redirects are bounded and revalidated. WAF-fronted feeds may still block cloud egress.

Run a recurring Task no more frequently than its previous run can finish. Concurrent runs of the same Task are not transactional and can race on shared state.

How it compares

ToolMulti-feedKeyword/regex filterCross-run dedup (only-new)Charges per new itemWebhookFor
This Actor✅ 1–500✅ keyword + regex + exclude✅ Task-keyed, durablepipelines / agents
automation-lab/rss-feed-reader➖ downstream❌ (dedup downstream)❌ per item every pollbulk reads
santamaria rss readerper feed-fetchbulk fetches
taroyamada feed aggregator✅ keywords✅ (manual snapshotKey)credit where due — closest peer
n8n RSS Trigger (free)➖ 1/node✅ (Filter node)❌ (needs custom staticData)n/a (compute)1–few feeds, self-host
Make "Watch RSS"➖ 1/module✅ but burns ops each polln/a (ops)Make-native flows
Inoreader / Feedly✅ (for reading)n/a (subscription)humans reading alerts

No trash talk — several of these are great at what they do. We own exactly one lane: scheduled, filtered, deduped, machine-readable feed deltas.

FAQ

What does the first run return? Everything currently matching (up to maxItemsPerRun), and it seeds the seen-set. Subsequent runs return only what's new since. To seed silently, set a low maxItemsPerRun on the first run.

A feed has no GUIDs — will I get duplicates? No. When guid is absent we key on link, and if that's missing too, on a stable hash of feedUrl + title + pubDate. We also guard against WordPress-style GUID rotation (same link+title, new guid → treated as already seen).

A feed keeps re-surfacing old items. They're suppressed while within dedupWindow. If they resurface after it, they re-deliver — raise the window if that's unwanted.

Does editing keywords or feeds reset my history? No — state is keyed by Task, not by your config.

Why did a run "succeed" with a dead feed? Per-feed isolation: the dead feed is an error row in the run summary (and unbilled); the rest of the run proceeds. Check the OUTPUT record for per-feed detail.

Can it fetch the full article text? No — it returns what the feed provides (content:encoded when present). Article-page extraction is a different, costlier job.

JSON Feed? Not yet — it returns a clear per-feed error rather than failing the run.

Support

Found a bad feed or an edge case? Open an issue on the Actor's Issues tab with the feed URL — feed pathology is exactly what this Actor is built to handle well, and reports make it better.