# RSS/Atom Feed Delta Monitor — Never Miss a New Item (`stubbie/rss-feed-delta-monitor`) Actor

Watches any RSS 2.0, RSS 1.0 or Atom feed and remembers which items it already returned, so a scheduled run only returns and charges for items published since the last check. A quiet feed costs nothing. No headless browser, one HTTP request per feed.

- **URL**: https://apify.com/stubbie/rss-feed-delta-monitor.md
- **Developed by:** [Marco Jakobsen](https://apify.com/stubbie) (community)
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 feed change detecteds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## RSS/Atom Feed Delta Monitor

### What it does

Point this Actor at any RSS 2.0, RSS 1.0 (RDF) or Atom feed — a company blog, a newsroom,
a podcast, a job board's own feed, a changelog — and it remembers which items it has
already delivered to you. Run it on a schedule and by default it returns (and only charges
you for) items published **since your last check**. A quiet feed with nothing new produces
zero rows and costs nothing. No headless browser, no HTML scraping, no login: one plain
HTTP request per feed, parsed straight from the XML the publisher already put there for
exactly this purpose.

This is built to be left running, not re-run by hand. The market for RSS readers on this
Store is full of tools that return the whole feed every single time — which is why most of
them only see a handful of runs per user a month even though buyers in this category
schedule as often as 300+ runs a user when the tool actually tracks state. Point this at
your watch-list once, schedule it hourly or daily, and your feed only ever shows you what
changed.

Typical uses: tracking a competitor's blog or newsroom for new posts, watching a vendor's
changelog for releases, turning a podcast feed into a "new episode" alert, feeding new job
postings from a board's own RSS into your pipeline, building a personal or team digest of
several sources without re-reading everything each time.

### Input

| Field | Type | Default | Notes |
|---|---|---|---|
| `feedUrls` | array of strings | — (required) | RSS 2.0, RSS 1.0 (RDF) or Atom feed URLs, one per item. |
| `onlyNew` | boolean | `true` | When true, a feed with nothing new since the last check returns zero rows — no charge. The very first check of any feed always returns a baseline (its newest items, up to the cap below). Set to `false` to always pull the current top items, ignoring memory. |
| `maxItemsPerFeed` | integer | `25` | Caps rows (and charge) a single feed can produce in one run — protects you from a surprise bill on a feed's first baseline check or a feed that replaced its whole history. |
| `stateStoreName` | string | `RSS-FEED-MONITOR-STATE` | Name of the memory that stores which items each feed has already delivered. Use a different name per independent watch-list if you run more than one. |
| `requestTimeoutSecs` | integer | `20` | Per-feed fetch timeout, 5–60 seconds. |

See `test-input.json` in this Actor for a working example.

### Output

One dataset row per new item (see `onlyNew` above). Example row:

```json
{
  "feedUrl": "https://example.com/feed/",
  "feedTitle": "Example Blog",
  "itemId": "https://example.com/2026/09/28/new-post",
  "title": "New Post Title",
  "link": "https://example.com/2026/09/28/new-post",
  "publishedAt": "Mon, 28 Sep 2026 08:00:00 GMT",
  "author": "Jane Doe",
  "summary": "A short description or excerpt from the feed itself.",
  "categories": ["Engineering"],
  "isFirstCheck": false,
  "checkedAt": "2026-09-28T08:12:00.000Z"
}
```

A feed that failed to fetch instead produces a row carrying only `feedUrl`, `checkedAt`
and an `error` field — not charged, so a temporarily-down feed does not silently disappear
from your run history.

### Pricing

Pay-per-event. You are charged **$0.015 per new item returned** (about $15 per 1,000
items) — not per feed checked and not per run. A run across 20 feeds where nothing new was
published on any of them produces zero rows and costs you nothing beyond compute. Schedule
this hourly or daily on the sources you actually care about; your bill tracks what changed,
never how often you looked.

# Actor input Schema

## `feedUrls` (type: `array`):

RSS 2.0, RSS 1.0 (RDF) or Atom feed URLs to watch, one per item — a blog feed, a newsroom feed, a podcast feed, a job-board feed, anything that publishes one.

## `onlyNew` (type: `boolean`):

When true (recommended for scheduled runs), a feed with nothing new since your last run returns zero rows and costs nothing. The first check of any feed always returns a baseline (its newest items, up to the cap below). Turn this off to always pull the current top items on every run, ignoring memory.

## `maxItemsPerFeed` (type: `integer`):

Caps how many rows (and how much you're charged) a single feed can produce in one run — protects you from a surprise bill on the very first baseline check of a huge feed, and from a feed that replaced its whole history.

## `stateStoreName` (type: `string`):

Name of the named key-value store used to remember which items each feed has already delivered. Leave the default unless you are running several independent watch-lists and want them to keep separate memory.

## `requestTimeoutSecs` (type: `integer`):

How long to wait for each feed to respond before giving up on it.

## Actor input object example

```json
{
  "feedUrls": [
    "https://hnrss.org/frontpage",
    "https://techcrunch.com/feed/",
    "https://www.theverge.com/rss/index.xml"
  ],
  "onlyNew": true,
  "maxItemsPerFeed": 25,
  "stateStoreName": "RSS-FEED-MONITOR-STATE",
  "requestTimeoutSecs": 20
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `csv` (type: `string`):

No description

## `console` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "feedUrls": [
        "https://hnrss.org/frontpage",
        "https://techcrunch.com/feed/",
        "https://www.theverge.com/rss/index.xml"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("stubbie/rss-feed-delta-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "feedUrls": [
        "https://hnrss.org/frontpage",
        "https://techcrunch.com/feed/",
        "https://www.theverge.com/rss/index.xml",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("stubbie/rss-feed-delta-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "feedUrls": [
    "https://hnrss.org/frontpage",
    "https://techcrunch.com/feed/",
    "https://www.theverge.com/rss/index.xml"
  ]
}' |
apify call stubbie/rss-feed-delta-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,stubbie/rss-feed-delta-monitor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/5vr7eADc5VGbTC4gB/builds/IMXXCJebt5Ab4pLVx/openapi.json
