# RSS Feed Reader: RSS & Atom to JSON/CSV, New Items Only (`phaux/rss-feed-reader`) Actor

Read RSS, Atom and JSON feeds and return clean items. Use to get the latest posts from blogs, news or podcasts, or set onlyNewItems on a schedule to monitor feeds. Input: feedUrls, maxItemsPerFeed, onlyNewItems, publishedAfter. Output per item: title, link, published, author, summary, categories.

- **URL**: https://apify.com/phaux/rss-feed-reader.md
- **Developed by:** [Phaux](https://apify.com/phaux) (community)
- **Categories:** News, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 feed parseds

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 Feed Reader: RSS & Atom to JSON/CSV, New Items Only

Paste in RSS, Atom or JSON Feed links. You get one clean row per item with title, link, date, author and summary. Turn on "only new items" and schedule the Actor, and each run returns only what is new since the last run, so it works as a simple feed monitor. It asks servers whether a feed has changed before downloading it again, and it respects robots.txt. A feed that fails or hasn't changed costs nothing beyond the small run fee.

### Quick start for AI agents and API users

- **What it does:** Read RSS, Atom and JSON feeds and return clean items.
- **When to use it:** To get the latest posts from blogs, news or podcasts, or set onlyNewItems on a schedule to monitor feeds.
- **Example input** (the form's prefill; it finishes in under a minute):

```json
{
  "feedUrls": [
    "https://www.nasa.gov/news-release/feed/",
    "https://blog.apify.com/rss/"
  ],
  "maxItemsPerFeed": 20,
  "onlyNewItems": false
}
```

- **Example output:** one real dataset row from run `lUlcDde6poQDPs3HA` (2026-10-23), with long fields shortened and empty fields left out. Fields not shown are listed in the output table below.

```json
{
  "feedUrl": "https://www.nasa.gov/news-release/feed/",
  "feedTitle": "NASA",
  "id": "45f6085a558e29a12d82",
  "guid": "https://www.nasa.gov/?p=1058847",
  "title": "NASA, Virginia Launch Power Partnership for Energy Security",
  "link": "https://www.nasa.gov/centers-and-facilities/langley/nasa-power-energy-partnership/",
  "published": "2026-10-23T17:50:21Z",
  "updated": "2026-10-23T17:50:21Z",
  "author": "Holly Rink",
  "summary": "NASA is helping to foster long-term energy security in Virginia. NASA’s Langley Research Center in Hampton, Virginia, is partnering with ...",
  "categories": [
    "Langley Research Center"
  ],
  "feedFormat": "rss20",
  "fetchedAt": "2026-10-23T18:55:25Z"
}
```

- **Cost (pay per event, Free-plan prices):** Actor run started $0.001; Feed parsed $0.002. Failed items are not charged.
- **From an AI agent:** with the Apify MCP server, call `call-actor` with actor `phaux/rss-feed-reader`, or load it as its own tool with `https://mcp.apify.com?tools=phaux/rss-feed-reader`. Read results with `get-dataset-items`.

### What does this RSS feed reader do?

- **Reads many feeds in one run** (up to 2,000): RSS 0.9x/1.0/2.0, Atom 0.3/1.0 and JSON Feed 1.x, including podcast feeds.
- **Normalises every item** to the same fields: `title`, `link`, `published` and `updated` (ISO 8601 UTC), `author`, plain-text `summary`, `categories`, `enclosures` (podcast audio, images) and an optional full `contentHtml`.
- **Only new items:** with `onlyNewItems` it remembers what it returned before (in a named key-value store) and returns only new items. Schedule it hourly or daily for a feed monitor, and connect the output to Slack, email, Google Sheets or a webhook with Apify integrations.
- **Conditional requests:** sends `If-None-Match` / `If-Modified-Since`, so an unchanged feed is a tiny `304` response and is not charged.
- **Filters:** `publishedAfter` date and `maxItemsPerFeed`.
- **Polite:** robots.txt, one request at a time per host with a delay, honest User-Agent, no proxies; an HTTP 429 stops requests to that host.

### Why use it?

- **Cheap for schedules:** a $0.001 run fee plus $0.002 per feed that returned items. Hourly monitoring of 10 feeds costs at most about $15 a month, and less when feeds don't change.
- **Failures are free:** broken, blocked, unchanged or empty feeds are not charged; each is listed in `FEEDS_REPORT` with the reason.
- **Clean, consistent output** across feed formats, ready for CSV/Excel, databases or LLM pipelines.

Use cases: news and blog monitoring, competitor and press-release tracking, podcast episode lists, content aggregation, alerting on new posts, and feeding new articles into AI summaries.

### How to use it

1. Add your feed URLs under **Feed URLs**.
2. Set **Max items per feed**. For monitoring, switch on **Only new items** and add a schedule (Console → Schedules).
3. Run it and export the **Items** dataset, or connect an integration.

### Input example

```json
{
  "feedUrls": ["https://www.nasa.gov/news-release/feed/", "https://blog.apify.com/rss/"],
  "maxItemsPerFeed": 20,
  "onlyNewItems": false
}
```

| Field | Default | Description |
|---|---|---|
| `feedUrls` | — | RSS, Atom or JSON Feed URLs. Empty = small example. |
| `maxItemsPerFeed` | `50` | Newest items per feed. |
| `onlyNewItems` | `false` | Return only items not returned in earlier runs. |
| `stateStoreName` | `rss-feed-reader-state` | Named store for the seen-items state (one per monitor). |
| `publishedAfter` | — | Only items published on/after this date. |
| `includeContent` | `false` | Add the full content HTML when the feed has it. |
| `maxSummaryLength` | `1000` | Plain-text summary length (0 = none). |
| `requestIntervalSecs` | `1` | Delay between requests to one host. |
| `maxConcurrency` | `10` | Feeds fetched in parallel (across hosts). |

### Output example

```json
{
  "feedUrl": "https://www.nasa.gov/news-release/feed/",
  "feedTitle": "NASA",
  "id": "a54d1aa6de416bf8dfb9",
  "guid": "https://science.nasa.gov/directorates/smd/faster-to-science-a-letter-to-the-science-community/",
  "title": "Faster to Science: A Letter to the Science Community",
  "link": "https://science.nasa.gov/directorates/smd/faster-to-science-a-letter-to-the-science-community/",
  "published": "2026-10-22T00:00:16Z",
  "updated": "2026-10-22T00:00:16Z",
  "author": null,
  "summary": "NASA Science wants to deliver science faster, so we're changing how we compete and select missions. ...",
  "categories": ["Science Mission Directorate"],
  "enclosures": null,
  "feedFormat": "rss20",
  "fetchedAt": "2026-10-22T01:13:00Z"
}
```

`FEEDS_REPORT` (key-value store) has one entry per feed: `ok`, `unchanged` (304), `no_new_items`, `empty` or `failed` with an error code (`robots_disallowed`, `http_error`, `not_a_feed`, `rate_limited`, `dns_error`, `timeout`, `not_supported` ...).

### Pricing

| Event | Price |
|---|---|
| Actor run started (once per run) | $0.001 |
| Feed parsed (per feed that returned at least one item) | $0.002 |

Example: one run over 25 feeds that all have items costs $0.001 + 25 × $0.002 = **$0.051**. Feeds that are unchanged, empty, have no new items or fail are free.

### Notes

- Output contains only what each feed publishes; the Actor does not open or scrape the linked articles.
- Google News RSS is not supported (its robots.txt disallows `/rss`).
- Some publishers allow their feeds for personal use only. You are responsible for following each feed's terms.

# Actor input Schema

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

RSS, Atom or JSON Feed URLs (up to 2,000). Empty = a small example run.

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

Newest items returned per feed (1–10,000). Default: 50.

## `onlyNewItems` (type: `boolean`):

Return only items not seen in earlier runs (state is kept in a named key-value store). Ideal with a schedule. Items already in the feed at the previous run count as seen. Default: false.

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

Named key-value store that remembers seen items. Use different names for independent monitors. Example: "my-news-monitor". Default: "rss-feed-reader-state".

## `publishedAfter` (type: `string`):

Only items published on/after this date (e.g. 2026-10-01 or 2026-10-01T12:00:00Z).

## `includeContent` (type: `boolean`):

Also return the item's full content (content:encoded / Atom content) as HTML, when the feed provides it. Default: false.

## `maxSummaryLength` (type: `integer`):

Summary is plain text cut to this many characters (0 = no summary). Default: 1000.

## `requestIntervalSecs` (type: `number`):

Politeness delay per host (0.5–30 s). A longer robots.txt Crawl-delay wins. Default: 1.

## `maxConcurrency` (type: `integer`):

Feeds fetched at once across hosts (one host is always fetched one request at a time). Default: 10.

## Actor input object example

```json
{
  "feedUrls": [
    "https://www.nasa.gov/news-release/feed/",
    "https://blog.apify.com/rss/"
  ],
  "maxItemsPerFeed": 20,
  "onlyNewItems": false,
  "stateStoreName": "rss-feed-reader-state",
  "includeContent": false,
  "maxSummaryLength": 1000,
  "requestIntervalSecs": 1,
  "maxConcurrency": 10
}
```

# Actor output Schema

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

No description

## `feeds` (type: `string`):

No description

## `runStats` (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://www.nasa.gov/news-release/feed/",
        "https://blog.apify.com/rss/"
    ],
    "maxItemsPerFeed": 20,
    "onlyNewItems": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("phaux/rss-feed-reader").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://www.nasa.gov/news-release/feed/",
        "https://blog.apify.com/rss/",
    ],
    "maxItemsPerFeed": 20,
    "onlyNewItems": False,
}

# Run the Actor and wait for it to finish
run = client.actor("phaux/rss-feed-reader").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://www.nasa.gov/news-release/feed/",
    "https://blog.apify.com/rss/"
  ],
  "maxItemsPerFeed": 20,
  "onlyNewItems": false
}' |
apify call phaux/rss-feed-reader --silent --output-dataset

```

## MCP server setup

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

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/QKPYP8UnDuwKr3ckk/builds/hgbOdL1LzmV4Cdiws/openapi.json
