# RSS Feed Aggregator — Feedly Alternative (`khadinakbar/feedly-alternative`) Actor

Aggregate RSS, Atom, and JSON feeds into a clean article dataset. Discover advertised feeds from supplied websites, filter keywords, tag sources, and remove duplicates for research and recurring news workflows.

- **URL**: https://apify.com/khadinakbar/feedly-alternative.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** News, Automation, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 article collecteds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## RSS Feed Aggregator — Feedly Alternative

Aggregate RSS, Atom, and JSON feeds into a clean article dataset. Discover advertised feeds from supplied websites, filter keywords, tag sources, and remove duplicates for research and recurring news workflows. For news researchers, each dataset record is one normalized feed article with its source tags and available publication details.

### Workflow: put the results to work

Provide trusted feed URLs or websites that advertise a feed. Set inclusion and exclusion terms to match the research brief, then review source-tagged articles before passing them to an alert or summary workflow. Account folders and saved-reading features stay in your chosen reader.

### Best fit and focused standalone workflow

Choose this Actor for news monitoring, competitive intelligence, industry research, and agent workflows that need a bounded export from trusted public feed sources. start with public feeds, collect a clean dataset, then pass the source-tagged output to your own spreadsheet, database, alert, or analysis workflow. Feedly-style account organization, saved reading, and private newsletter delivery remain separate workflows, while this Actor keeps the public-feed collection step portable and transparent.

### What you get

One dataset item represents one retained article. Fields remain consistent across RSS, Atom, and JSON Feed sources.

| Field | Meaning |
| --- | --- |
| `title`, `url`, `summary`, `content` | Cleaned article metadata and feed-provided text |
| `sourceName`, `sourceTags`, `feedUrl`, `sourceUrl` | Provenance and source grouping |
| `publishedAt`, `updatedAt`, `author`, `categories` | Feed-provided editorial metadata, nullable where absent |
| `matchedKeywords` | Requested include terms that matched the entry |
| `feedType`, `collectedAt` | Detected format and collection timestamp |

### Input

Give each source a public feed URL or a website homepage. Website URLs are examined for an advertised alternate feed link, and the run summary records the resolved feed URL and source diagnostics so you can confirm provenance for each collection.

```json
{
  "sources": [
    {
      "url": "https://hnrss.org/frontpage",
      "name": "Hacker News",
      "tags": ["technology", "startups"]
    },
    {
      "url": "https://www.theverge.com/rss/index.xml",
      "tags": ["technology"]
    }
  ],
  "includeKeywords": ["AI", "open source"],
  "excludeKeywords": ["sponsored"],
  "publishedWithinHours": 168,
  "maxItems": 100,
  "sortOrder": "newest",
  "deduplicateBy": "url"
}
```

`maxItems` is a whole-run cap, not a per-source limit. The Actor checks this cap before each write, so it also bounds the main per-article event charge.

### Example output

```json
{
  "id": "https://example.com/research/article",
  "title": "A research headline",
  "url": "https://example.com/research/article",
  "sourceName": "Example Research",
  "sourceTags": ["technology"],
  "author": "Example Author",
  "categories": ["Research"],
  "summary": "A feed-provided summary.",
  "content": null,
  "publishedAt": "<ISO 8601 publication timestamp>",
  "updatedAt": null,
  "matchedKeywords": ["AI"],
  "feedUrl": "https://example.com/feed.xml",
  "sourceUrl": "https://example.com",
  "feedType": "rss",
  "collectedAt": "<ISO 8601 collection timestamp>"
}
```

### Outcome records

Every terminal path writes `OUTPUT` and `RUN_SUMMARY`.

- `COMPLETE`: all readable sources were processed and retained items were written.
- `PARTIAL`: useful items were written and the summary records the portion of source coverage completed.
- `VALID_EMPTY`: readable feeds had no items matching the filters.
- `INVALID_INPUT`: source URLs or limits can be corrected by the caller.
- `UPSTREAM_FAILED`: the summary records source-level connectivity or feed-format diagnostics before the run ends.

### API

Use the `khadinakbar/feedly-alternative` Actor endpoint with your own Apify API token.

```bash
curl -X POST "https://api.apify.com/v2/acts/khadinakbar~feedly-alternative/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"sources":[{"url":"https://hnrss.org/frontpage","tags":["technology"]}],"maxItems":25}'
```

### Prompt card for an agent

> As an AI agent, collect up to 50 recent articles from these trusted public RSS feeds. Keep items mentioning AI or cybersecurity, use URL deduplication, and return title, URL, source tags, published time, summary, matched keywords, source URL provenance, collection time, outcome, and dataset readback guidance within the stated cost cap.

### Workflow scenario: from feeds to a daily brief

A research lead starts with five trusted industry feeds, adds a source tag for each publisher, and sets a 24-hour window. The Actor then combines the entries, applies the team’s include terms, and exports the newest source-tagged dataset items. Next, the lead groups articles by `sourceTags`, checks `matchedKeywords` and `publishedAt`, and passes the resulting list into a daily brief or alert workflow. Scheduling the same saved input creates consistent snapshots that make source changes easy to analyze over time.

### Best results and practical guidance

- Prefer direct RSS, Atom, or JSON Feed URLs when known. Website discovery follows declared feed links and records the selected `feedUrl`.
- Tag sources by subject, customer, competitor, or region so a downstream workflow can group them without re-parsing feeds.
- Use `includeKeywords` for a narrow alert feed and use an empty list for archival or broad monitoring.
- Schedule a saved task for recurring snapshots. The output keeps each run’s source-level provenance and applies deduplication within that collection.

### Builder's note

I designed this Actor around the cleanest reliable contract I found in feed monitoring: public syndication feeds already supply structured updates, so collection should preserve source metadata and make filter and cost boundaries visible. The design keeps one record per feed entry, names the resolved feed URL, and places source diagnostics in `RUN_SUMMARY`, which makes an automation easier to inspect and compose.

### Legal and responsible use

Collect only public sources you are authorized to monitor and follow each publisher’s terms, copyright rules, and robots directives. Article text comes from the feed payload, preserving a clear boundary between syndicated content and publisher pages.

### Pricing and run costs

This Actor uses **Pay per event plus Apify platform usage**. The [Pricing tab](https://apify.com/khadinakbar/feedly-alternative/pricing) lists the current event rates and billing terms.

| Event | Billing unit | When it applies |
|---|---|---|
| `apify-actor-start` | Actor Start | Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event). |
| `article-collected` | Article collected | One normalized public-feed article successfully saved to the dataset. |

Run cost combines the charged events and Apify platform usage. Review the run charge limit and requested result count before starting.

### Independent alternative

This Actor provides the specific workflow described above. It is not affiliated with or endorsed by Feedly; the named product and its trademarks belong to their respective owners.

### Connect an AI agent

Use the [Apify MCP configurator](https://mcp.apify.com) to choose an available client connection. Inspect this Actor’s current input schema and required credentials before running it.

# Actor input Schema

## `sources` (type: `array`):

Public RSS, Atom, JSON Feed, or website URLs to aggregate, for example https://hnrss.org/frontpage or https://example.com/blog. Website URLs are checked for an advertised RSS, Atom, or JSON Feed link. Provide 1 to 50 distinct HTTP(S) URLs. This is not a Feedly account export, authenticated page, or browser bookmark.

## `includeKeywords` (type: `array`):

Optional case-insensitive terms that must match an article title, summary, content, author, or category, for example AI or cybersecurity. Leave empty to retain every parsed article. At least one term must match when this list is used. These are literal contains checks, not boolean search syntax or regular expressions.

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

Optional case-insensitive terms that remove matching articles, for example giveaway or sponsored. Leave empty to keep all otherwise eligible entries. Any matching exclusion wins over an include match. These are literal contains checks, not regular expressions or source-level blocks.

## `publishedWithinHours` (type: `integer`):

Optional rolling age limit in hours, for example 24 for a daily monitoring feed. Use 0 to keep entries regardless of publication date, which is the default. Entries without a publication date remain eligible because many valid feeds omit one. This is not a scheduled polling interval.

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

Maximum number of normalized articles persisted for the entire run, for example 100. Defaults to 100 and accepts 1 to 1000. The actor stops writing before this cap so article event charges cannot exceed it. This is not a per-source limit.

## `sortOrder` (type: `string`):

Controls the dataset order after feeds are combined: newest keeps the most recent dated entries first, while oldest reverses that order. Entries without dates follow dated entries because their chronology cannot be verified. Defaults to newest. This does not change the order at the remote source.

## `deduplicateBy` (type: `string`):

Select URL to remove entries with the same canonical article URL, ID to use each feed entry's identifier, or none to preserve every source occurrence. URL is the default and suits most multi-source news monitoring. Deduplication happens only within this run. This does not mark or remember articles across separate runs.

## Actor input object example

```json
{
  "sources": [
    {
      "url": "https://hnrss.org/frontpage",
      "name": "Hacker News",
      "tags": [
        "technology",
        "startups"
      ]
    }
  ],
  "includeKeywords": [
    "AI",
    "cybersecurity"
  ],
  "excludeKeywords": [
    "sponsored"
  ],
  "publishedWithinHours": 24,
  "maxItems": 100,
  "sortOrder": "newest",
  "deduplicateBy": "url"
}
```

# Actor output Schema

## `articles` (type: `string`):

Filtered, source-tagged, deduplicated article records.

## `output` (type: `string`):

Compact terminal outcome and result count.

## `runSummary` (type: `string`):

Detailed source diagnostics and billing counters.

# 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 = {
    "sources": [
        {
            "url": "https://hnrss.org/frontpage",
            "name": "Hacker News",
            "tags": [
                "technology"
            ]
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/feedly-alternative").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 = { "sources": [{
            "url": "https://hnrss.org/frontpage",
            "name": "Hacker News",
            "tags": ["technology"],
        }] }

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/feedly-alternative").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 '{
  "sources": [
    {
      "url": "https://hnrss.org/frontpage",
      "name": "Hacker News",
      "tags": [
        "technology"
      ]
    }
  ]
}' |
apify call khadinakbar/feedly-alternative --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,khadinakbar/feedly-alternative"
        }
    }
}

```

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/I28Be8TrqK5wZeeRO/builds/RXd4pepXgDqUGE6Nm/openapi.json
