# RSS, Atom and JSON Feed Reader (`sampon/rss-atom-feed-reader`) Actor

Read RSS, Atom and JSON Feed items from feed or website addresses, one row per item with clean dates, with an option to return only items that are new since the last run.

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

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## 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 and JSON Feed Reader

Most news sites, blogs, podcasts and public agencies publish a feed: a machine-readable list of their latest posts. This Actor reads those feeds and gives you one clean row per item, with the dates already converted to one format, whatever flavour of feed the site uses.

It is meant for people who watch a set of sources on a schedule: switch on "Only items not returned before" and each run returns just the posts that appeared since the previous run.

### What you put in

A list of feed addresses:

```json
{
  "startUrls": [
    { "url": "https://www.nasa.gov/news-release/feed/" },
    { "url": "https://www.federalreserve.gov/feeds/press_all.xml" }
  ],
  "maxItemsPerFeed": 20
}
```

If you don't know the feed address, give the website instead. The Actor looks for the feed the page announces in its header, and if there is none it tries the usual places such as `/feed`, `/rss.xml` and `/atom.xml`.

Supported formats: RSS 2.0, RSS 1.0 (RDF), Atom 1.0 (and the old 0.3) and JSON Feed 1.0 / 1.1.

Optional settings:

| Setting | What it does |
|---|---|
| `maxItemsPerFeed` | How many items to keep from each feed, newest first. Default 20. |
| `onlyNewItems` | Remember what was returned and skip it next time. See below. |
| `stateStoreName` | The name of the storage that holds that memory. Use one name per task. |
| `keywords` | Keep only items whose title, summary or categories contain one of these words. |
| `postedWithinDays` | Skip items older than this. Items with no date at all are kept. |
| `includeSummary` | Turn off if you only need titles, dates and links. |
| `summaryMaxLength` | Cut summaries to this many characters, at a word boundary. Default 500. |

#### Only new items

With `onlyNewItems` on, the Actor stores an identifier for every item it has seen in a named key-value store in your account. The next run skips those items. The first run returns the newest items up to your maximum and marks everything currently in the feed as seen, so later runs never come back with old posts. If a feed can publish more items between two runs than your maximum, raise the maximum.

Running two different monitoring tasks? Give each its own `stateStoreName` so they don't share a memory.

### What you get

```json
{
  "feedTitle": "FRB: Press Release - All Releases",
  "feedUrl": "https://www.federalreserve.gov/feeds/press_all.xml",
  "feedType": "rss2",
  "siteUrl": "https://www.federalreserve.gov/feeds/feeds.htm",
  "title": "Federal Reserve Board releases results of the 2025 Survey of Consumer Finances, ...",
  "url": "https://www.federalreserve.gov/newsevents/pressreleases/other20261009a.htm",
  "guid": "https://www.federalreserve.gov/newsevents/pressreleases/other20261009a.htm",
  "published": "2026-10-09T14:00:00Z",
  "updated": null,
  "categories": ["Other Announcements"],
  "summary": "Federal Reserve Board releases results of the 2025 Survey of Consumer Finances, ...",
  "imageUrl": null,
  "enclosureUrl": null,
  "enclosureType": null,
  "language": null,
  "inputUrl": "https://www.federalreserve.gov/feeds/press_all.xml",
  "error": null,
  "scrapedAt": "2026-10-10T08:12:40Z"
}
```

- `published` and `updated` are always UTC in the form `YYYY-MM-DDTHH:MM:SSZ`, whether the feed wrote them as `Thu, 09 Oct 2026 10:00:00 EDT`, as ISO 8601 with an offset, or as a bare date.
- `feedType` is `rss2`, `rss1`, `atom` or `json`.
- `imageUrl` comes from the item's media tags, an image enclosure, or the first image in its content. `enclosureUrl` is the attached file, for example a podcast episode.
- `summary` is plain text, without HTML.

The rows describe posts, not people. Author names are never collected, and e-mail addresses and phone numbers inside summaries and titles are replaced with `[email removed]` and `[phone removed]`.

#### When something goes wrong

A run does not stop because one source is broken. An input that cannot be read gets one row with the reason in `error` and the other fields empty, for example `HTTP 404`, `the XML could not be parsed (...)`, `this is a web page and no readable feed was found at the usual feed addresses`, or `robots.txt of this site does not allow reading this address`. Filter on `error` being empty if you only want items.

### Price

Free for now. You only pay Apify's usual platform usage. A typical run is short: in our test, the two example feeds above (30 items) were read in under a second. A per-item price may be added later. If that happens, it will be shown on this page before it applies to you.

### How it treats the sites it reads

- Feeds are the address a site publishes for programs to read, so the Actor normally makes one request per feed.
- It follows each site's robots.txt, including any crawl delay, and understands the `*` and `$` patterns used in modern robots.txt files.
- By default it makes at most two requests at a time and waits at least half a second between requests to the same site. You can slow it down, but not beyond four parallel requests.

### Limits

- Only what the feed contains is returned. Many sites put a short excerpt in their feed rather than the full article, and most feeds list only their latest 10 to 50 posts. The Actor does not open the article pages.
- Feeds that need a login, or that are blocked by the site's robots.txt, are not read.
- Badly formed feeds are repaired where it is safe (stray `&`, HTML entities such as `&nbsp;`, control characters). Feeds that declare their own XML entities are refused for safety.
- Dates the feed does not provide stay empty. Some feeds only give a date without a time; those are read as midnight UTC.

This Actor is an independent tool. It is not made by, or affiliated with, the publishers of the feeds it reads.

# Actor input Schema

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

Feed addresses (RSS, Atom or JSON Feed), or website addresses. For a website, the feed announced in the page header is used, and if there is none, common locations such as /feed and /rss.xml are tried.

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

The newest items are kept first.

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

Remember which items were returned and skip them on later runs. The first run returns everything (up to the maximum) and starts the memory. Useful for scheduled runs.

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

Name of the key-value store in your account that holds the list of items already returned. Use a different name for each separate task. Only used when 'Only items not returned before' is on.

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

Keep only items whose title, summary or categories contain one of these words (case does not matter).

## `postedWithinDays` (type: `integer`):

Skip items older than this. Items without any date are kept. Leave empty to get everything.

## `includeSummary` (type: `boolean`):

The item's summary or content as plain text, with e-mail addresses and phone numbers masked. Turn off if you only need titles, dates and links.

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

Longer summaries are cut at a word boundary.

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

How many feeds to load at the same time. Capped at 4.

## `requestDelayMs` (type: `integer`):

A longer crawl delay in the site's robots.txt always wins.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.nasa.gov/news-release/feed/"
    },
    {
      "url": "https://www.federalreserve.gov/feeds/press_all.xml"
    }
  ],
  "maxItemsPerFeed": 20,
  "onlyNewItems": false,
  "stateStoreName": "rss-atom-feed-reader-state",
  "includeSummary": true,
  "summaryMaxLength": 500,
  "maxConcurrency": 2,
  "requestDelayMs": 500
}
```

# Actor output Schema

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

One row per feed item: feed, title, link, dates, categories, summary and image. Inputs that could not be read get one row with the reason in 'error'.

# 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://www.nasa.gov/news-release/feed/"
        },
        {
            "url": "https://www.federalreserve.gov/feeds/press_all.xml"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("sampon/rss-atom-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://www.nasa.gov/news-release/feed/" },
        { "url": "https://www.federalreserve.gov/feeds/press_all.xml" },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("sampon/rss-atom-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://www.nasa.gov/news-release/feed/"
    },
    {
      "url": "https://www.federalreserve.gov/feeds/press_all.xml"
    }
  ]
}' |
apify call sampon/rss-atom-feed-reader --silent --output-dataset

```

## MCP server setup

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