# RSS and Atom Feed Reader: feed items to JSON, CSV or Excel (`examsens.ai/rss-feed-reader`) Actor

Reads RSS 2.0, RSS 1.0, Atom and JSON Feed feeds, finds a site's feeds from its page, and returns every item with the same fields: title, link, dates in UTC, author, plain text summary, content, categories, image and enclosures.

- **URL**: https://apify.com/examsens.ai/rss-feed-reader.md
- **Developed by:** [Ed Rayyis](https://apify.com/examsens.ai) (community)
- **Categories:** News, Automation
- **Security:** Limited permissions
- **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 processeds

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 and Atom Feed Reader: feed items to JSON, CSV or Excel

Give it feed URLs or plain site addresses and it returns every item as one row, with the same field names whatever the feed format. One run can read many feeds of different formats.

It reads RSS 2.0, RSS 1.0 (RDF), Atom 1.0, and JSON Feed 1.0 and 1.1. Dates come out in UTC as ISO 8601 (`2026-10-03T21:23:10Z`), whether the feed wrote them as RFC 822 or ISO dates. The summary comes out as plain text with the HTML stripped, and relative links are turned into full URLs.

### Finding a site's feeds

Enter a page address, such as `https://example.com/blog`, and it reads the feeds the page names in its `<link rel="alternate">` tags. Some pages name a comments feed after the main one, so by default only the first feed is read. Raise "Feeds per web page" to read more. When the page names no feed, it tries the usual feed paths on the same site, such as `/feed`, `/rss`, `/feed.xml` and `/rss.xml`. An address without `https://` works too.

### Input

- Feed or site URLs (required)
- Maximum items per feed (default 100). Counted after the filters below, in the order the feed lists its items.
- Published on or after: a date such as `2026-10-01` or `2026-10-01T08:00:00Z`. A date the run cannot read stops the run with an error.
- Maximum age in days: for scheduled runs. When both date filters are set, the later cutoff applies.
- Keep items with no date (default on): whether a date filter keeps items the feed gives no date for.
- Keywords: keep only items whose title, summary or categories contain one of the words or phrases. Whole words only, so `rust` does not match "trust". Not case sensitive.
- Include full content (default on): the item's full HTML in `contentHtml`.
- Find feeds on web pages (default on), and feeds per web page (default 1).
- Remove duplicates (default on): an item found in two feeds of the run is output once, matched on its ID, or its link when it has no ID.
- Request timeout in seconds (default 30). A feed that answers HTTP 503 is tried again, up to three attempts in all.

### Output

Dataset: one row per item with:

- `title`, `link`, `guid`, `author`
- `publishedAt` and `updatedAt` in UTC. For an Atom entry with no published date, `publishedAt` holds its updated date.
- `description`: the summary as plain text
- `contentHtml`: the full content as HTML, when the feed carries it
- `categories`: a list of tags
- `imageUrl`: from the feed's media tags, or the first image in the content
- `enclosures`: a list of attached files with `url`, `type` and `length`, such as podcast audio
- `commentsUrl`, when the feed gives one
- `feedUrl`, `feedTitle`, `feedFormat` (such as `RSS 2.0`, `Atom 1.0` or `JSON Feed 1.1`), `feedLanguage`, `startUrl` and `fetchedAt`

Export as JSON, CSV or Excel, or read it over the API.

The key value store holds a `SUMMARY` record with one entry per feed: the feed URL, title and format, whether it was found through link tags or the usual paths, the number of items in the feed and the number output, the newest and oldest item dates, and the error when a feed could not be read (for example HTTP 404, or no feed found on a page).

### Pricing

Pay per event: one event per feed item output. Items removed by the filters or as duplicates, and feeds that fail, are not charged. Set the maximum items per feed to control cost. The run stops when it reaches the maximum charge you set.

### Scope and conduct

It downloads the feed files and the pages you enter as start URLs. The articles the items link to are never requested. No personal data is collected beyond what the feeds publish, such as author names.

### Support

Questions and problems: the Issues tab on this page. Replies are written by an AI assistant on behalf of the developer and reviewed by the developer.

# Actor input Schema

## `startUrls` (type: `array`):

Feed URLs (RSS, Atom or JSON Feed), or web page addresses such as https://example.com/blog. For a web page, the feeds it names in its link tags are read.

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

Output at most this many items from each feed, counted after the date and keyword filters, in the order the feed lists them. Each item output is one billable event.

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

Output only items published at or after this date, such as 2026-10-01 or 2026-10-01T08:00:00Z. A date without a time zone is read as UTC.

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

Output only items published within this many days before the run. Useful for scheduled runs. When both date filters are set, the later cutoff applies.

## `includeUndated` (type: `boolean`):

When a date filter is set, keep items whose feed gives no publication date (or one that cannot be read). Turn off to drop them.

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

Output only items whose title, summary or categories contain at least one of these words or phrases. Not case sensitive. Leave empty to output all.

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

Add the item's full HTML content (contentHtml) when the feed carries it. Turn off for smaller output.

## `discoverFeeds` (type: `boolean`):

When a start URL is a web page, read the feeds it names in its link tags. When it names none, try the usual feed paths on the same site, such as /feed and /rss.xml.

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

How many of the feeds found on a web page to read, in page order. Some pages name a comments feed after the main one.

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

Output an item once when it appears in more than one feed of the run, matched on its ID, or its link when it has no ID.

## `timeoutSecs` (type: `integer`):

Time allowed for each HTTP request.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://hnrss.org/frontpage"
    },
    {
      "url": "https://github.blog/feed/"
    }
  ],
  "maxItemsPerFeed": 100,
  "includeUndated": true,
  "includeContent": true,
  "discoverFeeds": true,
  "maxFeedsPerSite": 1,
  "deduplicate": true,
  "timeoutSecs": 30
}
```

# 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 = {
    "startUrls": [
        {
            "url": "https://hnrss.org/frontpage"
        },
        {
            "url": "https://github.blog/feed/"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("examsens.ai/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 = { "startUrls": [
        { "url": "https://hnrss.org/frontpage" },
        { "url": "https://github.blog/feed/" },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("examsens.ai/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 '{
  "startUrls": [
    {
      "url": "https://hnrss.org/frontpage"
    },
    {
      "url": "https://github.blog/feed/"
    }
  ]
}' |
apify call examsens.ai/rss-feed-reader --silent --output-dataset

```

## MCP server setup

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