# RSS Feed Reader: RSS, Atom & JSON Feed Alerts (`maliksaid/rss-feed-reader`) Actor

RSS feed reader and monitor. Read RSS, Atom and JSON Feed from feed URLs, website URLs or OPML files. Get title, link, date, author, categories, summary and enclosure in one JSON schema. Dedupe feeds, filter by keywords and get only new items for alerts.

- **URL**: https://apify.com/maliksaid/rss-feed-reader.md
- **Developed by:** [Malik Said](https://apify.com/maliksaid) (community)
- **Categories:** News, AI, Automation
- **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 items

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 & JSON Feed Alerts

RSS Feed Reader reads RSS, Atom and JSON Feed and returns every item in one clean schema. Give it feed URLs, website URLs or OPML files. For a website, it finds the feed link in the page head.

Each item has the title, link, publish date, update date, author name, categories, a short summary and the enclosure URL. The same article in two feeds is saved once. Include and exclude keywords keep only the items you care about.

Turn on monitor mode and schedule the Actor. Each run then returns only new items. Use it for news alerts, competitor blog tracking, podcast episode lists and AI agent inputs.

### RSS feed formats supported

| Format | Versions | Notes |
|---|---|---|
| RSS | 2.0, 0.91, 0.92 | Includes `dc:creator`, `content:encoded`, `media:content` and podcast enclosures |
| RSS 1.0 (RDF) | 1.0 | Dublin Core dates, creators and subjects |
| Atom | 1.0 | `xml:base`, text, HTML and XHTML content, enclosure links |
| JSON Feed | 1.0, 1.1 | `authors`, `tags` and `attachments` |
| OPML | 1.0, 2.0 | Reads every `xmlUrl` the file lists |
| Website page | Any HTML | Reads `<link rel="alternate">` feed links. If there is none, it tries `/feed`, `/rss.xml`, `/feed.xml`, `/atom.xml` and `/index.xml` |

### RSS feed data you get

| Field | Meaning |
|---|---|
| `feedUrl`, `feedTitle`, `feedType`, `siteUrl`, `feedLanguage` | The feed the item came from |
| `title` | Item title |
| `link` | Link to the article on the publisher's site |
| `guid` | Item ID as the feed publishes it |
| `published`, `updated` | Dates in ISO 8601 UTC |
| `authorName` | Author names as published. Email addresses are removed |
| `categories` | Categories or tags |
| `summary` | Plain-text snippet, 200 characters by default. Never the full article |
| `enclosureUrl`, `enclosureType`, `enclosureLength` | Attached media file, for example a podcast episode |
| `imageUrl` | Item image or thumbnail from the feed, or null. A link to the publisher's file. The image is never downloaded |
| `matchedKeywords` | Your include keywords that the item matched |
| `alsoInFeeds` | Other input feeds that carried the same item |
| `id` | Stable ID. Monitor mode uses it to spot new items |

Sample record from a test run on 21 October 2026:

```json
{
    "id": "05b4b37dda9435ebfb591ad8",
    "feedUrl": "https://blog.rust-lang.org/feed.xml",
    "feedTitle": "Rust Blog",
    "feedType": "atom",
    "siteUrl": "https://blog.rust-lang.org/",
    "feedLanguage": "en",
    "title": "Announcing rustup 1.29.2",
    "link": "https://blog.rust-lang.org/2026/10/20/Rustup-1.29.2/",
    "guid": "https://blog.rust-lang.org/2026/10/20/Rustup-1.29.2/",
    "published": "2026-10-20T00:00:00.000Z",
    "updated": "2026-10-20T00:00:00.000Z",
    "authorName": "The Rustup Team",
    "categories": [],
    "summary": "The rustup team is happy to announce the release of rustup version 1.29.2. Rustup is the recommended tool to install Rust, a programming language that empowers everyone to build reliable and...",
    "enclosureUrl": null,
    "enclosureType": null,
    "enclosureLength": null,
    "imageUrl": null,
    "matchedKeywords": [],
    "alsoInFeeds": [],
    "scrapedAt": "2026-10-21T14:28:50.643Z"
}
```

A field is `null` or empty when the feed does not publish it. The Actor never fills a gap with a guess.

Items are sorted newest first across all feeds. Items without a date come last.

### How to use the RSS feed reader

1. Paste feed URLs, website URLs or OPML file URLs into **Feed or site URLs**.
2. Optional: add **Include keywords** such as `funding` or `outage`. Add **Exclude keywords** to drop noise.
3. Optional: set **Maximum item age** to keep only recent items.
4. Run the Actor. Open the **Overview** table or download JSON, CSV or Excel.
5. For alerts, turn on **Monitor mode** and add a schedule. Connect a webhook, Slack, email or Make to the run to get new items.

Each run also saves a `FEED_REPORT` record in the key-value store. It lists every input, the feed it resolved to, the item count, and why any feed was skipped.

### Input

| Option | Default | Meaning |
|---|---|---|
| Feed or site URLs | 3 sample feeds | Feeds, websites or OPML files. Up to 1,000 feeds per run |
| Include keywords | None | Keep items that match at least one. Latin words match whole words. Arabic words match inside words |
| Exclude keywords | None | Drop items that match any of these |
| Maximum item age (days) | 0 (any age) | Keep only items from the last N days |
| Monitor mode | Off | Return only items not returned before |
| Monitor state key | `default` | Use one key per watch list |
| Maximum items | 100 | Stop after this many items. Set 0 for no limit |
| Maximum items per feed | 0 (all) | Take only the newest N items of each feed |
| Summary length | 200 | Characters in the snippet, 500 at most. 0 removes it |
| Feeds per website | 1 | How many discovered feed links to read per website |
| Try common feed paths | On | Try `/feed` and similar when a page links to no feed |

Example input:

```json
{
    "feedUrls": ["https://www.nasa.gov/news-release/feed/", "https://blog.rust-lang.org/"],
    "keywords": ["Mars", "release"],
    "monitorMode": true,
    "stateKey": "space-and-rust",
    "maxItems": 0
}
```

### RSS feed reader pricing

You pay a small fee per run and a fee for each item saved to your dataset. Items dropped by your filters, and items that monitor mode already returned, cost nothing. See the exact prices on the Pricing tab. Apify's free plan credit covers many small runs.

### FAQ

**Does it copy full articles?** No. It saves the title, link, dates, author name, categories and a short snippet. Follow the link to read the article on the publisher's site.

**Does it return images?** Yes, as a link. `imageUrl` holds the item's thumbnail or first image as the feed publishes it, or null when the feed has none. The Actor never downloads or stores the image itself.

**Does it respect robots.txt?** Yes. It reads robots.txt for every host before it fetches a page or a feed. A disallowed feed is skipped and listed in `FEED_REPORT`. It also waits at least 1 second between requests to the same host.

**Can it read feeds behind a login or a bot challenge?** No. Those feeds are skipped.

**How does it find duplicates?** It compares links after it removes tracking parameters such as `utm_source`, the `www.` prefix and the trailing slash. Without a link it uses the feed's item ID.

**How long does monitor mode remember items?** It remembers an item while the item is still in a feed, and for 180 days after it leaves.

### Data sources and use

- The Actor reads only the URLs you give it, plus robots.txt.
- Each publisher sets its own terms. Check them before you republish feed content.
- It does not collect email addresses or other contact details.

### Related Actors

- [Regulator Circulars Monitor](https://apify.com/maliksaid/regulator-circulars-monitor) tracks new circulars from financial regulators.
- [Technical SEO Audit](https://apify.com/maliksaid/technical-seo-audit) checks a website for SEO issues and broken links.

### Support

Report a problem in the Issues tab. Include the run link and the feed URL.

# Actor input Schema

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

Add RSS, Atom or JSON Feed URLs, website URLs or OPML file URLs. For a website, the Actor finds the feed link in the page head. For an OPML file, it reads every feed the file lists. Up to 1,000 feeds per run.

## `keywords` (type: `array`):

Keep only items whose title, categories or summary contain at least one keyword. Latin keywords match whole words. Arabic keywords match anywhere in a word. Leave empty to keep every item.

## `excludeKeywords` (type: `array`):

Drop items whose title, categories or summary contain any of these keywords.

## `maxAgeDays` (type: `integer`):

Keep only items published in the last N days. Items without a date are kept. Set 0 to keep items of any age.

## `monitorMode` (type: `boolean`):

Return only items that earlier monitor-mode runs with the same state key did not return. Schedule the Actor with this on to get alerts for new items.

## `stateKey` (type: `string`):

Name the memory that monitor mode uses. Use a different key for each separate watch list.

## `maxItems` (type: `integer`):

Stop after saving this many items, newest first. The default keeps test runs short and cheap. Set 0 for no limit.

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

Take at most this many of the newest items from each feed. Set 0 to take every item.

## `summaryLength` (type: `integer`):

Cut each summary to this many characters. The Actor never saves full article text. Set 0 for no summary.

## `maxFeedsPerSite` (type: `integer`):

Read this many of the feed links found on a website page. Comment feeds come last.

## `guessFeedPaths` (type: `boolean`):

Try paths such as /feed and /rss.xml when a website page links to no feed.

## Actor input object example

```json
{
  "feedUrls": [
    "https://www.nasa.gov/news-release/feed/",
    "https://blog.rust-lang.org/",
    "https://www.jsonfeed.org/feed.json"
  ],
  "keywords": [],
  "excludeKeywords": [],
  "maxAgeDays": 0,
  "monitorMode": false,
  "stateKey": "default",
  "maxItems": 100,
  "maxItemsPerFeed": 0,
  "summaryLength": 200,
  "maxFeedsPerSite": 1,
  "guessFeedPaths": true
}
```

# Actor output Schema

## `results` (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.rust-lang.org/",
        "https://www.jsonfeed.org/feed.json"
    ],
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("maliksaid/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.rust-lang.org/",
        "https://www.jsonfeed.org/feed.json",
    ],
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("maliksaid/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.rust-lang.org/",
    "https://www.jsonfeed.org/feed.json"
  ],
  "maxItems": 100
}' |
apify call maliksaid/rss-feed-reader --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maliksaid/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/lyLtXTb7efs4iCsuu/builds/R9ckM7baCe11hgqX5/openapi.json
