RSS to JSON API — RSS, Atom & JSON Feed Parser avatar

RSS to JSON API — RSS, Atom & JSON Feed Parser

Pricing

$1.00 / 1,000 feed item normalizeds

Go to Apify Store
RSS to JSON API — RSS, Atom & JSON Feed Parser

RSS to JSON API — RSS, Atom & JSON Feed Parser

Parse public RSS, Atom, and JSON feeds into one stable dataset and API. Filter items and optionally emit only new content across scheduled runs.

Pricing

$1.00 / 1,000 feed item normalizeds

Rating

0.0

(0)

Developer

Kunteper Koyu

Kunteper Koyu

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

0

Monthly active users

15 hours ago

Last modified

Share

Turn many public RSS 2.0, Atom, and JSON Feed URLs into one stable JSON dataset. Use this feed parser and RSS-to-JSON API for news monitoring, content pipelines, RAG ingestion, alerts, aggregation, and scheduled change detection.

Why use it

  • one normalized schema across RSS, Atom, and JSON Feed
  • bulk feed input with bounded concurrency
  • keyword and publication-date filters
  • deterministic SHA-256 fingerprints for deduplication
  • persistent incremental mode that emits and charges only unseen items
  • configurable per-feed and total result limits
  • safe public-URL validation and bounded downloads

Common use cases

  • aggregate company blogs, news, podcasts, or industry sources
  • create a filtered news-monitoring or alert pipeline
  • normalize content before RAG ingestion or summarization
  • convert RSS/Atom to JSON for an application or automation
  • schedule runs and detect new or changed items by fingerprint

Quick start

  1. Click Try for free or Run.
  2. Add public RSS, Atom, or JSON Feed URLs.
  3. Optionally add search terms or a publication cutoff.
  4. Run the Actor and consume the normalized dataset.
{
"feedUrls": ["https://blog.apify.com/rss/"],
"searchTerms": ["AI", "automation"],
"publishedAfter": "2026-01-01",
"maxItemsPerFeed": 100,
"maxItemsTotal": 1000,
"concurrency": 5,
"timeoutSeconds": 30,
"incrementalMode": true,
"incrementalFirstRun": "baselineOnly",
"incrementalStoreName": "my-news-monitor",
"seenRetentionDays": 90
}

New-items-only scheduled runs

Set incrementalMode to true and reuse the same incrementalStoreName across runs. On the first run, incrementalFirstRun: "baselineOnly" remembers current items without emitting or charging them as result events; "emitAll" delivers the current backlog. Later runs emit only fingerprints not already stored. seenRetentionDays and maxSeenItems bound the history, so expired or evicted items can appear again. Use a different store name for every independent monitor and avoid overlapping runs that write to the same store.

Example result

{
"feedUrl": "https://blog.apify.com/rss/",
"feedTitle": "Apify Blog",
"feedType": "rss",
"itemId": "https://blog.apify.com/example-post/",
"title": "Example post",
"url": "https://blog.apify.com/example-post/",
"author": "Apify",
"summary": "A normalized feed item summary.",
"publishedAt": "2026-07-01T12:00:00.000Z",
"categories": ["automation"],
"fingerprint": "a-stable-sha256-fingerprint",
"retrievedAt": "2026-07-11T12:00:00.000Z"
}

The values above illustrate the output schema; live fields depend on each publisher's feed.

Run by API

Set APIFY_TOKEN in your environment and keep it secret.

cURL

curl -X POST \
"https://api.apify.com/v2/acts/rtworule~public-feed-normalizer/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"feedUrls":["https://blog.apify.com/rss/"],"maxItemsTotal":20,"incrementalMode":true,"incrementalStoreName":"my-apify-blog-monitor"}'

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('rtworule/public-feed-normalizer').call({
feedUrls: ['https://blog.apify.com/rss/'],
maxItemsTotal: 20,
incrementalMode: true,
incrementalStoreName: 'my-apify-blog-monitor',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("rtworule/public-feed-normalizer").call(run_input={
"feedUrls": ["https://blog.apify.com/rss/"],
"maxItemsTotal": 20,
"incrementalMode": True,
"incrementalStoreName": "my-apify-blog-monitor",
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)

Pricing

This Actor uses pay per event. A feed-item-normalized event costs $0.001 per stored item: 100 delivered items cost $0.10 and 1,000 cost $1.00 in event charges. Apify applies a $0.01 minimum run charge. Filters, result limits, and incremental mode help control output; the Actor also respects the run's maximum total charge. Incremental mode does not emit or charge previously remembered items as result events.

Integrations and automation

  • schedule a Task with incrementalMode: true to emit only unseen items
  • send new rows to Slack, email, Make, Zapier, n8n, or a webhook
  • load normalized content into a vector database, CMS, warehouse, or search index
  • export CSV/XLSX to Sheets for a lightweight editorial dashboard
  • use publishedAfter to limit recurring runs to a recent window

FAQ and troubleshooting

Does it discover feed URLs from a website homepage? No. Supply the direct public RSS, Atom, or JSON Feed URL.

How do I avoid processing the same item twice? Enable incrementalMode and reuse one unique incrementalStoreName for that monitoring stream. Choose baselineOnly on the first run to remember current items without emitting them, or emitAll to deliver the current backlog. You can also deduplicate downstream by fingerprint or itemId.

Can an old item appear again? Yes, after its fingerprint exceeds seenRetentionDays or the state exceeds maxSeenItems. Increase those bounds when a longer history matters.

Why are some fields empty? Feed standards allow publishers to omit author, summary, content, categories, or timestamps. The Actor does not invent missing source data.

Why was a feed rejected? The URL must be public HTTP/HTTPS without embedded credentials. Private, local, reserved, and metadata-service destinations are blocked, including redirects.

Why did parsing fail? Confirm the URL returns valid RSS, Atom, or JSON Feed rather than an HTML page. Publisher format errors and responses over 5 MB cannot be normalized.

Responsible use, limitations, and support

The Actor follows at most five validated public redirects, caps each response at 5 MB, and does not bypass authentication. Feed formats and publisher policies vary. Users are responsible for permission to access and reuse feed content, copyright obligations, retention, and downstream processing.

For an unexpected result from a valid public feed, open an issue from the Actor page with the run ID, feed URL, feed type, and expected behavior. Never include credentials or private feeds.

More tools from this developer