# Rss New Items (`eichan/rss-new-items`) Actor

- **URL**: https://apify.com/eichan/rss-new-items.md
- **Developed by:** [Eichan Jolly](https://apify.com/eichan) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.00 / 1,000 results

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 Recent Items Collector

Read **one** public RSS 2.0, RSS/RDF, or Atom feed and append recent articles to the Apify run's default dataset. A compact standard-library-only Actor designed for repeated scheduled snapshots.

### Who it is for

Newsroom watchers, blog readers, research teams, and automation builders who need normalized recent feed entries without feed-specific parsers, accounts, or API keys.

### Input example

```json
{
  "feedUrl": "https://feeds.bbci.co.uk/news/world/rss.xml",
  "sinceHours": 168,
  "maxItems": 20
}
```

| Field | Required | Description |
| --- | --- | --- |
| `feedUrl` | Yes | One public HTTP(S) RSS/Atom feed URL. The form prefills **one feed**. |
| `sinceHours` | No | Lookback in hours, default `168` (7 days); `0` disables date filtering. |
| `maxItems` | No | Maximum dataset items, default `20`, maximum `100`. |

### Output example

One dataset row per unique qualifying article (sample values are illustrative):

```json
{
  "title": "Example headline",
  "url": "https://example.org/articles/123",
  "publishedAt": "2026-11-01T03:45:00Z",
  "guid": "article-123",
  "checkedAt": "2026-11-01T04:00:00Z"
}
```

- `title`: article title (up to 500 characters).
- `url`: HTTP(S) article URL (relative links resolved against feed URL).
- `publishedAt`: parsed RFC 2822/RFC 3339 date in UTC, or `null` if dates are not required and no parseable date exists.
- `guid`: publisher GUID or Atom ID, if supplied; otherwise `null`.
- `checkedAt`: UTC timestamp captured at run start.

Newest parseable dates are emitted first. Duplicate GUIDs (or URLs if no GUID exists) within a **single run** are removed.

### Scheduling use case

Run daily with `sinceHours: 24` and `maxItems: 50`. Export the resulting dataset to a workflow that aggregates articles and deduplicates across runs using `guid` or `url`.

**Important:** "Recent" means an article's published timestamp falls within the lookback window. This Actor is **not** a persistent new-item detector: repeated runs can produce the same articles. The Actor does not read or alter another run's dataset. When `sinceHours > 0`, undated or unparseable-date entries are excluded; set `sinceHours: 0` if you need those.

### Limits and behavior

- Only a single public feed; no website/feed discovery, authentication, login, credentials, or external API keys.
- Feed downloads limited to **1 MB**, HTTP timeout **20 seconds**, public IP destinations on HTTP(S) ports 80/443 only; private/local networks are rejected.
- Only RSS/Atom XML, not HTML, JSON Feed, or JavaScript-rendered content. DTD/entity-declaring feeds are rejected.
- No content extraction or article body crawling. A feed can be temporarily empty or contain malformed publication dates.
- No persistent state, notifications, or guaranteed exactly-once delivery. Source server restrictions, DNS, and rate limits apply.
- Failed runs print plain-English `ERROR:` messages and exit unsuccessfully, without tracebacks. A valid empty result creates no dataset rows.
- The Apify platform provides the run's own storage token automatically. **No user-supplied Apify token** is needed; it is used only for that run's input and default dataset, not as an external feed API key.

### Run / deploy

**Cloud:** Upload the entire folder as one Apify Actor project, build it, and run it using the Console-generated input form. The Actor uses the standard Apify run environment (`APIFY_IS_AT_HOME`, `APIFY_TOKEN`, storage IDs) through the built-in Python `urllib` module; it does **not** install the Apify SDK.

**Local:** Place a JSON file at `storage/key_value_stores/default/INPUT.json` in this Actor folder and run:

```bash
python src/main.py
```

Results appear as one JSON object per file under `storage/datasets/default/`. Or build and run the Docker image using an appropriate mounted `storage/` directory.

### Store placement / pricing suggestion

- **Category:** Automation (primary)
- **Additional categories:** News, Developer tools
- **Suggested monetization:** Pay per event, **per Actor run** (e.g. a provisional **$0.005/run** `actor-start` event), not per article, because published article counts vary and old articles may reappear across runs. This amount is only a starting hypothesis; validate platform costs and market pricing first.
- **Billing status:** Pricing is a **recommendation only**. No pay-per-event charge is emitted by this code. Configure/store-test Apify PPE charging separately before publishing as a paid Actor. Alternatively publish as pay-per-usage (platform costs only).

# Actor input Schema

## `feedUrl` (type: `string`):

One public HTTP(S) RSS or Atom feed URL.

## `sinceHours` (type: `integer`):

Include only entries with parseable publication dates within this many hours. Set 0 to include all, including undated items. This is NOT persisted new-item detection.

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

Maximum number of deduplicated dataset records.

## Actor input object example

```json
{
  "feedUrl": "https://feeds.bbci.co.uk/news/world/rss.xml",
  "sinceHours": 168,
  "maxItems": 20
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing the Actor's result items

# 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 = {
    "feedUrl": "https://feeds.bbci.co.uk/news/world/rss.xml"
};

// Run the Actor and wait for it to finish
const run = await client.actor("eichan/rss-new-items").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 = { "feedUrl": "https://feeds.bbci.co.uk/news/world/rss.xml" }

# Run the Actor and wait for it to finish
run = client.actor("eichan/rss-new-items").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 '{
  "feedUrl": "https://feeds.bbci.co.uk/news/world/rss.xml"
}' |
apify call eichan/rss-new-items --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,eichan/rss-new-items"
        }
    }
}
```

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/SI3bAMgrL10I0cgy3/builds/hSQ2xQd9LHAwTvDDh/openapi.json
