# RSS Feed Reader & Finder (RSS, Atom, JSON Feed) (`pavel.tashev/rss-feed-reader`) Actor

RSS feed reader and feed finder: read RSS, Atom and JSON Feed items, or discover the feed of any website. Keyword and date filters, podcast enclosures, only-new-items mode for monitoring. Never charges for a failed or empty result.

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

## Pricing

from $1.00 / 1,000 feed item saved or feed founds

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

### What does RSS Feed Reader & Finder do?

**RSS Feed Reader & Finder reads RSS, Atom and JSON Feed items into clean, consistent JSON, and finds the feeds behind any website.** Give it feed URLs, or just websites and domains like `theverge.com`, and it returns one row per article, post, release or podcast episode: title, link, author, publication date, plain-text summary, full content, categories, images and podcast enclosures.

It runs on the Apify platform, so you get API access, scheduling, webhooks, integrations (Make, Zapier, n8n, Google Sheets, Slack) and run monitoring. Schedule it with **Only new items** turned on and you get a clean news, blog or podcast monitor that never saves (or charges for) the same item twice.

### You are never charged for a failed or empty result

Every result says what it is, and only real results cost anything.

| `status` | Meaning | Charged |
|---|---|---|
| `ok` | A real result | Yes |
| `empty` | Worked, but there was nothing to report | No |
| `failed` | Could not be done — the `error` field says why | No |
| `truncated` / `partial` | Cut short by a limit you set; what was delivered is kept | Only the delivered part |
| `skipped` | Not attempted, for example after the maximum cost per run was reached | No |

If every input fails, the run itself fails with an explanation instead of reporting success with no data.

### Why use RSS Feed Reader & Finder?

- **Paste websites, not just feeds.** Feeds are found automatically from the page's feed links and the usual locations (WordPress `/feed/`, Substack, Medium, Blogger, `/rss.xml`, `/atom.xml`, `/index.xml` and more).
- **Every feed format in one schema.** RSS 0.9x, 1.0 (RDF) and 2.0, Atom and JSON Feed 1.x, including podcast feeds with iTunes fields and enclosures.
- **Only new items on scheduled runs.** Remembers what earlier runs saved and uses conditional requests, so unchanged feeds cost almost nothing.
- **Filters that save money.** Keep items matching keywords or published within a period; duplicates across feeds are removed. Filtered and duplicate items are never charged.
- **Tolerant parsing.** Handles broken XML, invalid characters, HTML entities, gzip files and dozens of malformed date formats; dates come out as ISO 8601 UTC.

Typical uses: news and competitor monitoring, content curation and newsletters, feeding articles to AI agents and RAG pipelines, podcast catalogues, release tracking (GitHub releases feeds), research alerts (arXiv) and Slack or email alerts through integrations.

### How to read RSS feeds or find a website's feed

1. Click **Try for free**.
2. In **Feed URLs or websites**, paste feed URLs or websites, one per line.
3. Optionally add **Keywords** or **Published after** (for example `7 days`).
4. Click **Start**. Most runs finish in seconds.
5. Open the **Output** tab: **Items** shows the newest items, **Details** shows everything else.

To only list the feeds a website offers, set **Mode** to **Find feeds only**. Both modes save (and charge for) at most **Feeds per website** feeds per URL, so raise that field if a site publishes several feeds you want to see.

### Input

| Field | Description | Default |
|---|---|---|
| **Feed URLs or websites** | Feed URLs, website URLs or bare domains. Up to 1,000 per run. | – |
| **Mode** | Read feed items, or find feeds only | Read feed items |
| **Maximum items per feed** | Items saved per feed, counted after filters | 100 |
| **Feeds per website** | How many feeds to use per URL when a site offers several (both modes) | 1 |
| **Keywords** | Comma-separated; an item matches when all words of one keyword appear | – |
| **Published after** | A date (`2026-09-01`) or a period (`24 hours`, `7 days`, `2 weeks`) | – |
| **Only new items** | Skip items saved by earlier runs | off |
| **Remove duplicates across feeds** | Same story in several feeds is saved once | on |
| **Include full content** / **Content format** | Full article body as plain text or HTML | off / text |
| **Summary length** | Characters of the plain-text summary (0 = full) | 500 |

Example input:

```json
{
  "urls": ["https://feeds.npr.org/510289/podcast.xml", "theverge.com", "https://hnrss.org/newest?q=AI"],
  "keywords": "ai, electric cars",
  "publishedAfter": "7 days",
  "onlyNewItems": true
}
```

### Output

A real item from a run on 15 September 2026 (enclosure URL shortened):

```json
{
  "id": "69c6d43ca753b6933f59",
  "feedUrl": "https://feeds.npr.org/510289/podcast.xml",
  "feedTitle": "Planet Money",
  "feedType": "rss",
  "siteUrl": "https://www.npr.org/podcasts/510289/planet-money",
  "title": "The loan at the heart of a new foreclosure crisis",
  "link": "https://www.npr.org/2026/09/11/nx-s1-5966574/baltimore-foreclosure-crisis-dscr-loan",
  "guid": "e4a2224f-f462-445a-9401-ad628eaee491",
  "author": "NPR",
  "publishedAt": "2026-09-11T21:00:00+00:00",
  "updatedAt": null,
  "summary": "There is a new type of loan that is sweeping through the country right now. It’s advertised as a super quick and super easy way to get a mortgage to buy a home. In recent years, Wall Street has been…",
  "categories": [],
  "enclosures": [{ "url": "https://npr.simplecastaudio.com/.../default.mp3", "type": "audio/mpeg", "length": 27996248 }],
  "imageUrl": "https://npr.brightspotcdn.com/dims3/default/strip/false/crop/3377x1900+0+1/resize/1280/...",
  "duration": "1749",
  "language": "en",
  "error": null,
  "scrapedAt": "2026-09-15T11:50:11+00:00"
}
```

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel. A per-URL summary (feeds found, items saved, skipped, filtered, duplicates, errors) is saved in the key-value store as `FEEDS_REPORT`, under `inputs`, alongside `checkedAt` and `prunedRecords`. A URL where no feed could be read gets one row with an `error` message and suggestions; such rows are not charged.

### Output fields

| Field | Meaning |
|---|---|
| `title`, `link`, `guid` | Item title, permalink and the feed's unique ID |
| `author` | Byline (email addresses are removed); falls back to the feed's author |
| `publishedAt`, `updatedAt` | ISO 8601 UTC; Atom entries with only an update date use it as the publication date |
| `summary`, `content` | Plain-text summary; full content when **Include full content** is on |
| `categories`, `imageUrl` | Categories or tags, and the item's image |
| `enclosures`, `duration` | Podcast or media files (`url`, `type`, `length`) and episode duration |
| `feedUrl`, `feedTitle`, `feedType`, `siteUrl`, `language` | Where the item came from (`rss`, `rdf`, `atom` or `json`) |
| `inputUrl`, `discoveredVia`, `itemCount`, `latestItemAt` | In **Find feeds only** mode: the feeds found on each website |

### How much does it cost to read RSS feeds?

This Actor uses **pay-per-event pricing**: you pay for each item saved to your dataset (in **Find feeds only** mode, for each feed found). Filtered items, duplicates, items already saved by earlier runs, and URLs without a readable feed are never charged. See the **Pricing** tab for the current price per 1,000 results. Platform compute is included, and you can set a maximum cost per run; the Actor stops cleanly when it is reached.

### Tips for monitoring feeds on a schedule

- **Turn on Only new items** and schedule the Actor (for example hourly). Seen items are remembered in a key-value store named `rss-feed-reader-state` in your own Apify account; delete that store to start fresh. If you change keywords or limits, feeds are re-read in full once.
- **Feeds rarely change more often than every 15–60 minutes.** Running more often adds cost without adding items.
- **YouTube:** enter the channel feed (`https://www.youtube.com/feeds/videos.xml?channel_id=...`); YouTube pages themselves are not read.
- **Keyword matching uses whole words,** so `ai` does not match `rain`; list variants separately.

### Related tools

Process what the feeds link to:

- [PDF Text Extractor & Document to Markdown](https://apify.com/pavel.tashev/doc-to-markdown): convert PDF, Word, PowerPoint and Excel files (including scans) to Markdown for AI pipelines.
- [Audio & Video Transcriber](https://apify.com/pavel.tashev/audio-video-transcriber): turn audio, video and podcast episodes into text and subtitles.
- [Sitemap URL Extractor](https://apify.com/pavel.tashev/sitemap-url-extractor): list every URL of a website from its sitemaps, or only new and removed pages.

### FAQ, limitations and support

**What is stored between runs?** With *Only new items* on, the Actor keeps one small record per feed in a key-value store named `rss-feed-reader-state` in your own account, so a scheduled run knows what it already saved. After a run that reads every URL successfully, records for feeds you no longer list are deleted, so changing your feed list leaves nothing behind. A run that is cut short (cost limit, time limit, or a feed that failed) never deletes anything.

**Which feeds work?** Any public RSS, Atom or JSON Feed that doesn't need a login. Sites that block automated requests (HTTP 403/429) or disallow feed access in robots.txt are reported in `FEEDS_REPORT` and not charged.

**What happens when a site won't let us read its robots.txt?** Some sites put their `/robots.txt` behind bot protection and answer 403 or time out. We then can't tell what the site allows, so we follow one rule everywhere: **the address you entered is still read, and addresses we would have worked out ourselves are not.** A site with no robots.txt at all (404) is treated as allowing everything. For this Actor that means a feed address you paste is always read, while feed links we discover on a website are skipped at such a site and reported in `FEEDS_REPORT`.

**Does it scrape web pages?** No. It reads feeds that publishers provide for syndication, requests each feed once per run with a descriptive user agent, and respects robots.txt. Only a website's home page is read to find its feed links.

**Can I republish the content?** Feed content belongs to its publishers. Keep the `link` to the original and follow each publisher's terms.

**Missing a field or a feed that doesn't parse?** Open an issue in the **Issues** tab with the feed URL. Custom monitoring pipelines are welcome too.

# Actor input Schema

## `urls` (type: `array`):

RSS, Atom or JSON Feed URLs, or plain websites and domains (for example theverge.com). For websites, the feed is found automatically from the page's feed links and the usual feed locations. Up to 1,000 URLs per run; any extra entries are skipped and reported in the run status.

## `mode` (type: `string`):

Read feed items, or only list the feeds found on each website (one result per feed, with its title, type and item count).

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

Stop after this many items from each feed (counted after filters). Most feeds list their 10–100 newest items.

## `maxFeedsPerWebsite` (type: `integer`):

When a website advertises several feeds (for example posts, podcasts and comments), use up to this many. Applies to both modes: "Read feed items" reads this many feeds per website and "Find feeds only" lists this many. Raise it to see every feed a site publishes. Comment feeds are used only when nothing else exists.

## `keywords` (type: `string`):

Comma-separated keywords. An item is kept when its title, summary, content or categories contain all words of at least one keyword, for example "electric cars, battery". Leave empty for all items.

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

Keep only items published on or after a date (2026-09-01) or within a period ("24 hours", "7 days", "2 weeks"). Items without a date are dropped when this is set.

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

Skip items saved by earlier runs, and ask servers whether the feed changed since last time. Remembered items are kept in a key-value store named rss-feed-reader-state in your own Apify account. Skipped items are not charged.

## `deduplicate` (type: `boolean`):

Save a story once even when several feeds carry it (matched by link, GUID, or title and date). Duplicates are not charged.

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

Add the full article body when the feed provides it (content:encoded, Atom content, JSON Feed content).

## `contentFormat` (type: `string`):

Full content as plain text or as the original HTML.

## `summaryMaxLength` (type: `integer`):

Maximum characters of the plain-text summary. Use 0 for the full summary.

## Actor input object example

```json
{
  "urls": [
    "https://feeds.bbci.co.uk/news/world/rss.xml",
    "https://daringfireball.net"
  ],
  "mode": "items",
  "maxItemsPerFeed": 20,
  "maxFeedsPerWebsite": 1,
  "onlyNewItems": false,
  "deduplicate": true,
  "includeContent": false,
  "contentFormat": "text",
  "summaryMaxLength": 500
}
```

# Actor output Schema

## `items` (type: `string`):

No description

## `feedsReport` (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 = {
    "urls": [
        "https://feeds.bbci.co.uk/news/world/rss.xml",
        "https://daringfireball.net"
    ],
    "maxItemsPerFeed": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("pavel.tashev/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 = {
    "urls": [
        "https://feeds.bbci.co.uk/news/world/rss.xml",
        "https://daringfireball.net",
    ],
    "maxItemsPerFeed": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("pavel.tashev/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 '{
  "urls": [
    "https://feeds.bbci.co.uk/news/world/rss.xml",
    "https://daringfireball.net"
  ],
  "maxItemsPerFeed": 20
}' |
apify call pavel.tashev/rss-feed-reader --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,pavel.tashev/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/0w5jGtbAMOPz1LMmD/builds/2Ik9MukeB20XngIfF/openapi.json
