# RSS to JSON API: RSS & Atom Feed Reader, Finds a Site's Feed (`fecklesspleb/rss-feed-reader`) Actor

Turn any RSS or Atom feed into clean JSON. Paste a website and it finds the feed. Keyword and date filters, only-new-items mode for schedules. $0.80 per 1K.

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

## Pricing

$0.80 / 1,000 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 to JSON API: read any RSS, Atom or JSON Feed, or find a website's feed automatically

RSS Feed Reader turns RSS, Atom, RDF and JSON Feed feeds into clean JSON. Paste feed URLs, or ordinary website URLs, and the Actor finds the site's feed for you (from the page's `<link rel="alternate">` tag or common paths such as `/feed` and `/rss.xml`). Every item comes back with the same fields whatever the feed format: title, link, author, publish date, summary, categories, image, media and, optionally, full content as text or HTML. Filter by keyword and date, and turn on monitoring mode to get only items you haven't seen before. You pay $0.0008 per item written to the dataset.

### Who it's for

- **Developers** who need an RSS to JSON converter they can call over HTTP or from Python and JavaScript.
- **Newsletter writers and content teams** building a digest from many blogs and news sites.
- **Marketing and PR teams** watching competitors' blogs and press pages for new posts.
- **No-code builders** sending new items from feeds to Slack, Notion, Airtable or Google Sheets with n8n, Make or Zapier.
- **AI and data teams** collecting fresh articles for summarization or a retrieval index.

### What data you get

One dataset item per feed entry:

| Field | What it holds |
|---|---|
| `feedUrl`, `feedTitle`, `siteUrl` | The feed that was read, its title and the site it belongs to. |
| `id` | The entry's GUID or ID (falls back to the link). |
| `title`, `link`, `author` | Entry title, URL and author when given. |
| `publishedAt`, `updatedAt` | ISO 8601 timestamps. |
| `summary` | The entry summary as plain text (up to 1,000 characters). |
| `categories` | Categories or tags. |
| `media`, `imageUrl` | Enclosures (podcast audio, images) and the main image when there is one. |
| `commentsUrl` | Comments link when the feed has one. |
| `contentText` / `contentHtml` | Full content when the feed includes it and `includeContent` is on. |
| `scrapedAt` | When the run read the item. |

Sample item (real output from theverge.com; long text shortened):

```json
{
  "feedUrl": "https://www.theverge.com/rss/index.xml",
  "feedTitle": "The Verge",
  "siteUrl": "https://www.theverge.com",
  "id": "https://www.theverge.com/?p=1021644",
  "title": "Adam Mosseri says negativity around AI is ‘going to get worse’",
  "link": "https://www.theverge.com/ai-artificial-intelligence/1021644/adam-mosseri-instagram-ai-negativity",
  "author": "Stevie Bonifield",
  "publishedAt": "2026-10-28T23:05:39+00:00",
  "updatedAt": "2026-10-28T23:05:39+00:00",
  "summary": "Asked about AI and the trend of college students booing tech CEOs at graduation ceremonies, Instagram head Adam Mosseri acknowledged in an interview that a lot of people really don't like AI, and it's not just young peop…",
  "categories": [
    "AI",
    "Instagram",
    "Meta",
    "News",
    "Social Media",
    "Tech"
  ],
  "media": [],
  "imageUrl": null,
  "commentsUrl": null,
  "contentText": "Asked about AI and the trend of college students booing tech CEOs at graduation ceremonies, Instagram head Adam Mosseri acknowledged in an interview that a lot of people really don't like AI, and it's not just young peop…",
  "scrapedAt": "2026-10-29T01:01:18.587993+00:00"
}
```

### How to use it

1. Add URLs to **Feed or website URLs**, one per line. Feed URLs and normal website URLs both work.
2. Optional: set limits and filters.
3. Click **Start**, then export from the **Output** tab as JSON, CSV, Excel or XML.

Default mode: if you leave **Feed or website URLs** empty, or keep only the sample feed `https://www.nasa.gov/feed/` that the form starts with, the run reads that NASA news feed and returns at most 10 items, charged at the normal per-item price (so at most $0.008). The log says `Default mode: no feed URLs given (or only the sample default), reading up to 10 sample items from https://www.nasa.gov/feed/`. Replace the sample with your own feeds for a normal run.

| Input field | Label | Notes |
|---|---|---|
| `feedUrls` | Feed or website URLs | Defaults to the sample NASA feed (default mode, at most 10 items). Add your own feeds for a normal run. |
| `maxItemsPerFeed` | Max items per feed | Default 100, newest first. 0 = all items in the feed. |
| `maxTotalItems` | Max items in total | 0 = no limit. |
| `keywords` | Keywords (any) | Keep items whose title, summary or categories contain any of these. |
| `excludeKeywords` | Exclude keywords | Drop items containing any of these. |
| `postedWithinDays` | Published within (days) | Only items from the last N days. Items without a date are kept (see the next row). |
| `keepUndatedItems` | Keep items without a date | Default `true`: with `postedWithinDays` set, items that have no date are kept and the log says how many. Set `false` to drop them. |
| `includeContent` | Include full content | Default `true`. Only adds content when the feed provides it. |
| `contentFormat` | Content format | `text` (default), `html` or `both`. |
| `onlyNewItems` | Only new items (monitoring) | Default `false`. Seen items are remembered for 90 days. |
| `stateStoreName` | State store name | Default `rss-feed-reader-state`. Use one name per monitor. |

Example input:

```json
{
  "feedUrls": [
    "https://www.theverge.com",
    "https://hnrss.org/frontpage"
  ],
  "maxItemsPerFeed": 50,
  "keywords": [
    "AI"
  ],
  "onlyNewItems": true
}
```

Up to 8 feeds are read in parallel. Duplicate entries within a run (same feed and ID) are skipped and not charged. `RUN_SUMMARY` in the default key-value store lists each feed with its status and item counts.

### Pricing

This Actor uses pay-per-event pricing: **$0.0008 per item** written to the dataset. That is **$0.80 per 1,000 items**. There is no separate start fee in this Actor's pricing (as listed on October 28, 2026; the Pricing tab on the Store page is the source of truth).

You are charged only for items that end up in your dataset. Items removed by your filters and items skipped in monitoring mode are not charged.

| Example | Items | Cost |
|---|---:|---:|
| One blog, latest 20 posts | 20 | $0.016 |
| 50 feeds, 20 items each | 1,000 | $0.80 |
| Daily monitoring of 50 feeds, ~100 new items a day for a month | 3,000 | $2.40 |

Rows are illustrations; real counts depend on how often your feeds publish.

Worked example: 1,000 items × $0.0008 = **$0.80**.

To cap spend, set **Maximum cost per run** in the run options (or `maxTotalChargeUsd` via the API). The Actor stops cleanly when the next item would go over the limit and records `stoppedByCostLimit: true` in the run summary.

### How it compares

Prices are from the public Apify Store listings on October 28, 2026.

| Option | Pricing model | What it is good at |
|---|---|---|
| This Actor | $0.0008 per item | Feed discovery from a website URL, one schema for RSS/Atom/RDF/JSON Feed, keyword and date filters, only-new-items mode. |
| RSS readers on the Store that charge per feed rather than per item | Per feed or per run | Can be cheaper for feeds with hundreds of items, since you don't pay per entry. |
| Free online RSS-to-JSON converters | Free or subscription | Good for one-off conversions. Usually no monitoring state or no-code integrations. |
| A library such as `feedparser` (Python) | Free | Best if you want to host your own code and scheduling. |

### Integrations and API

The actor ID is `fecklesspleb/rss-feed-reader` (in API URLs: `fecklesspleb~rss-feed-reader`).

**n8n, Make and Zapier.** Each has an Apify integration with a "run Actor" action. Pick `fecklesspleb/rss-feed-reader`, paste the input JSON shown below, then read the results from the run's default dataset in the next step. To process only new items on a schedule, turn on the monitoring option and run it from a schedule (Apify Schedules or a trigger in your automation tool).

**Webhooks and schedules.** Apify Schedules can run the Actor on a cron, and a webhook on "run succeeded" can call your own endpoint with the run ID.

**HTTP API.** Run the Actor and get the items back in one call. This waits for the run to finish, so use it for small runs:

```bash
curl -X POST "https://api.apify.com/v2/acts/fecklesspleb~rss-feed-reader/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"feedUrls": ["https://www.theverge.com", "https://hnrss.org/frontpage"], "maxItemsPerFeed": 50, "keywords": ["AI"], "onlyNewItems": true}'
```

**Python** (`pip install apify-client`):

```python
from decimal import Decimal
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("fecklesspleb/rss-feed-reader").call(
    run_input={
        "feedUrls": [
            "https://www.theverge.com",
            "https://hnrss.org/frontpage"
        ],
        "maxItemsPerFeed": 50,
        "keywords": [
            "AI"
        ],
        "onlyNewItems": True
    },
    max_total_charge_usd=Decimal("5"),  # optional spend cap
)
## apify-client 3.x returns a Run object; on 1.x/2.x use run["defaultDatasetId"]
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)
```

**JavaScript / Node.js** (`npm install apify-client`):

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fecklesspleb/rss-feed-reader').call(
    {
        "feedUrls": [
            "https://www.theverge.com",
            "https://hnrss.org/frontpage"
        ],
        "maxItemsPerFeed": 50,
        "keywords": [
            "AI"
        ],
        "onlyNewItems": true
    },
    { maxTotalChargeUsd: 5 }, // optional spend cap
);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Results can also be exported from the dataset as JSON, CSV, Excel, XML or RSS from the Apify Console or the dataset API.

### FAQ

**How do I convert an RSS feed to JSON?**
Paste the feed URL in `feedUrls` and run the Actor, or call the run-sync endpoint above. Each entry becomes one JSON object with the fields listed in "What data you get".

**What if I don't know the feed URL?**
Paste the website's home page. The Actor looks for the site's `<link rel="alternate">` feed tag, then tries common paths (`/feed`, `/rss`, `/rss.xml`, `/feed.xml`, `/atom.xml`, `/index.xml`, `/feeds/posts/default`, `/feed.json`). If none is found, the URL is reported in `RUN_SUMMARY` and skipped.

**Which formats are supported?**
RSS 0.9x/2.0, RSS 1.0 (RDF), Atom and JSON Feed 1.0/1.1. JSON Feed items come back with the same fields as RSS items (`authors` are joined into `author`, `tags` become `categories`, `attachments` become `media`). When the Actor looks for a site's feed it also uses `application/feed+json` links.

**How do I get only new posts?**
Turn on `onlyNewItems` and schedule the Actor. Items returned before are skipped and not charged. Use a separate `stateStoreName` for each independent monitor.

**Does it get the full article text?**
It returns the full content the feed itself includes (`content:encoded` or Atom content). It doesn't open article pages, so feeds that only publish a summary give you a summary.

**Can I read RSS to JSON from Python?**
Yes, use the Python snippet above. You get a list of dictionaries, ready for pandas or a database.

**Do I need an API key or login?**
No. The Actor reads public endpoints and needs no account on the source site. You only need an Apify account to run it. It obeys robots.txt and rate-limits requests per host. robots.txt is checked again on every redirect, so a URL that redirects to a disallowed path or another host is not followed. If a host's robots.txt can't be read (a server error, a network failure or a page that isn't a robots file), that host is skipped for the run and `RUN_SUMMARY` says why. A missing robots.txt means no rules.

### Related Actors

- [Hacker News Scraper](https://apify.com/fecklesspleb/hacker-news-scraper): Hacker News stories and comments, plus parsed "Who is hiring?" job posts.
- [Sitemap Extractor](https://apify.com/fecklesspleb/sitemap-extractor): every URL listed in a website's XML sitemaps.
- [ATS Jobs Scraper](https://apify.com/fecklesspleb/ats-jobs-scraper): jobs from Greenhouse, Lever, Ashby, Workable, Recruitee and Workday boards in one schema.
- [Remote Jobs Aggregator](https://apify.com/fecklesspleb/remote-jobs-aggregator): remote jobs from Remote OK, We Work Remotely and Jobicy, de-duplicated.

# Changelog

This Actor's version history is a separate document: https://apify.com/fecklesspleb/rss-feed-reader/changelog.md

# Actor input Schema

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

RSS, RDF, Atom or JSON Feed URLs, or normal website URLs (the Actor looks for the site's feed). Leave empty, or keep the sample NASA feed, for a default-mode run: up to 10 sample items from https://www.nasa.gov/feed/ at the normal per-item price.

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

Newest items first. 0 = all items in the feed.

## `maxTotalItems` (type: `integer`):

0 = no limit.

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

Keep items whose title, summary or categories contain any of these words.

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

Drop items that contain any of these words.

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

Only items published in the last N days. Items without a date are kept unless you turn off Keep items without a date.

## `keepUndatedItems` (type: `boolean`):

When Published within (days) is set, keep items that have no publish or update date, since their age can't be checked. Turn off to drop them.

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

Adds the full post content when the feed provides it.

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

Plain text, HTML, or both.

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

Skip items returned by earlier runs that used the same state store. Ideal for schedules.

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

Named key-value store that remembers seen items. Use a different name per monitor.

## Actor input object example

```json
{
  "feedUrls": [
    "https://www.nasa.gov/feed/"
  ],
  "maxItemsPerFeed": 100,
  "maxTotalItems": 0,
  "keepUndatedItems": true,
  "includeContent": true,
  "contentFormat": "text",
  "onlyNewItems": false,
  "stateStoreName": "rss-feed-reader-state"
}
```

# Actor output Schema

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

No description

## `summary` (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/feed/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fecklesspleb/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/feed/"] }

# Run the Actor and wait for it to finish
run = client.actor("fecklesspleb/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/feed/"
  ]
}' |
apify call fecklesspleb/rss-feed-reader --silent --output-dataset

```

## MCP server setup

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