# Documentation Change Monitor & Markdown Feed (`quarterly_drum_zzv/docs-change-feed`) Actor

Monitor documentation, API docs, help centers, and knowledge-base URLs. Emit clean Markdown and hashes only when meaningful content changes—ideal for RAG refreshes, AI agents, alerts, and scheduled change tracking.

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

## Pricing

from $1.00 / 1,000 page checks

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

## Docs Change Feed

Monitor documentation and knowledge-base pages and get clean Markdown **only when meaningful content changes**. Docs Change Feed is a stateful website change monitor built for AI agents, RAG pipelines, developer documentation, changelogs, policies, help centers, and API docs.

Give it one or more public URLs. The Actor extracts readable content, normalizes it to Markdown, hashes the result, remembers the previous version, and emits a dataset item when a page is new or changed. No LLM or external AI key is required.

### What you can automate

- **Refresh RAG knowledge only when sources change** instead of re-ingesting the same pages every run.
- **Monitor API and developer documentation** for updates that may affect integrations.
- **Track help centers, policies, changelogs, and product docs** on an Apify schedule.
- Feed clean Markdown change events into agents, webhooks, Make, Zapier, n8n, or your own API.
- Ignore noisy page elements such as timestamps or rotating banners with CSS selectors.

### Quick start

Use a single documentation page:

```json
{
  "urls": ["https://docs.example.com/guide"]
}
```

Or monitor several pages:

```json
{
  "urls": [
    "https://docs.example.com/guide",
    "https://docs.example.com/api"
  ],
  "emitOnlyChanged": true,
  "includeMarkdown": true
}
```

On the first successful check the page is reported as `new`. On later runs, unchanged pages are suppressed by default. When the normalized content changes, the Actor emits a `changed` result with both the new and previous SHA-256 hashes.

### Output data

Each result can contain:

- source, final, and canonical URL;
- page title;
- `new`, `changed`, `unchanged`, or `error` status;
- current and previous SHA-256 content hash;
- first-seen, checked, and previous-change timestamps;
- HTTP status, ETag, and Last-Modified metadata;
- normalized Markdown for new or changed pages.

This makes the dataset useful both as a human-readable change log and as a machine-readable trigger for downstream automation.

### Stateful change detection

Docs Change Feed stores the last known page state in an Apify key-value store. Later runs send conditional HTTP headers when the server supports them:

- `If-None-Match`
- `If-Modified-Since`

A `304 Not Modified` response avoids downloading and parsing the document again. Otherwise, the Actor extracts and normalizes the content before comparing its SHA-256 hash with the previous version.

The state store is configurable, so separate monitoring workflows can keep independent histories.

### Input options

#### Documentation URLs

`urls` is the list of public HTTP or HTTPS pages to monitor.

#### Emit only new or changed pages

`emitOnlyChanged` defaults to `true`. Set it to `false` when you also want an `unchanged` dataset record on every check.

#### Include Markdown

`includeMarkdown` defaults to `true`. Disable it when you only need status and hash metadata.

#### Extraction mode

Use `readability` for the main readable article/documentation content. Use `body` when the relevant content is spread across the full page body.

#### Ignore volatile elements

Use `removeSelectors` for CSS selectors that should not affect change detection:

```json
{
  "removeSelectors": [
    ".last-updated",
    ".rotating-banner",
    "[data-build-time]"
  ]
}
```

#### Persistent state store

`stateStoreName` lets different jobs maintain independent histories. The default is `docs-change-feed-state`.

### Run on a schedule or through the API

For continuous documentation monitoring, create an Apify schedule such as hourly or daily. Each scheduled run reuses the persistent state and returns only the events you asked for.

You can also call the Actor through the Apify API or integrate its dataset with automation platforms and AI-agent workflows. The default dataset view exposes compact change metadata; the full dataset item contains the detailed fields produced by the run.

### Pricing

The Actor uses **Pay Per Event** pricing:

- **$0.001 per page check**;
- Apify's Actor-start event is **$0.00005** per run.

The Actor checks the caller's maximum-charge budget before each URL. Large URL lists therefore remain bounded by the maximum cost configured for the run.

### Reliability and noise reduction

Content is normalized before hashing to reduce false positives from insignificant whitespace. For site-specific volatile elements, add `removeSelectors`.

HTTP validators are used when available, but not every website supplies reliable ETag or Last-Modified headers. Hash comparison remains the final content-change check.

### Limits and expected behavior

- Intended for public HTML documentation and content pages.
- It is not a browser automation Actor and does not execute complex client-side applications before extraction.
- Pages requiring login, CAPTCHA, private network access, or anti-bot bypass are outside the intended use case.
- A site can change markup in ways that affect extracted content even when the underlying article meaning is similar.
- Per-page timeout is configurable from 1 to 120 seconds.

### Privacy

The Actor fetches only URLs supplied in the run input. It does not send page content to an LLM, advertising network, analytics service, or third-party AI provider.

Run data and datasets follow the privacy and retention settings of your Apify account.

### FAQ

#### Can I use this for RAG document refresh?

Yes. Run it on a schedule and trigger re-embedding or re-indexing only for `new` and `changed` items.

#### Can I monitor several documentation sites at once?

Yes. Put all target pages in `urls`. Each URL keeps its own stored state.

#### Why did a page trigger even though the text looks similar?

Inspect the emitted Markdown and add unstable elements to `removeSelectors`. Build timestamps, navigation counters, or rotating banners are common causes.

#### Does it need OpenAI or another AI API key?

No. Extraction, normalization, hashing, persistence, and comparison are deterministic and do not require an LLM.

#### Can I get an output item for unchanged pages?

Yes. Set `emitOnlyChanged` to `false`.

# Actor input Schema

## `urls` (type: `array`):

Pages to monitor. State is kept between runs in a named key-value store.

## `emitOnlyChanged` (type: `boolean`):

When enabled, unchanged pages are suppressed from the output dataset.

## `includeMarkdown` (type: `boolean`):

Include normalized Markdown for new and changed pages.

## `extractionMode` (type: `string`):

Choose main-content extraction or conversion of the whole document body.

## `removeSelectors` (type: `array`):

Optional volatile elements to remove before hashing, such as .last-updated.

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

Named key-value store used to persist hashes and HTTP validators between runs.

## `timeoutMs` (type: `integer`):

Maximum time allowed for each HTTP request.

## Actor input object example

```json
{
  "urls": [
    "https://docs.apify.com/"
  ],
  "emitOnlyChanged": true,
  "includeMarkdown": true,
  "extractionMode": "readability",
  "removeSelectors": [],
  "stateStoreName": "docs-change-feed-state",
  "timeoutMs": 30000
}
```

# Actor output Schema

## `changeEvents` (type: `string`):

Dataset items for new, changed, or error results, including normalized Markdown when enabled.

# 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 = {
    "urls": [
        "https://docs.apify.com/"
    ],
    "emitOnlyChanged": false,
    "includeMarkdown": true,
    "extractionMode": "readability",
    "removeSelectors": [],
    "stateStoreName": "docs-change-feed-state",
    "timeoutMs": 30000
};

// Run the Actor and wait for it to finish
const run = await client.actor("quarterly_drum_zzv/docs-change-feed").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 = {
    "urls": ["https://docs.apify.com/"],
    "emitOnlyChanged": False,
    "includeMarkdown": True,
    "extractionMode": "readability",
    "removeSelectors": [],
    "stateStoreName": "docs-change-feed-state",
    "timeoutMs": 30000,
}

# Run the Actor and wait for it to finish
run = client.actor("quarterly_drum_zzv/docs-change-feed").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 '{
  "urls": [
    "https://docs.apify.com/"
  ],
  "emitOnlyChanged": false,
  "includeMarkdown": true,
  "extractionMode": "readability",
  "removeSelectors": [],
  "stateStoreName": "docs-change-feed-state",
  "timeoutMs": 30000
}' |
apify call quarterly_drum_zzv/docs-change-feed --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,quarterly_drum_zzv/docs-change-feed"
        }
    }
}
```

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/Z7rkopda6KhbHQMIO/builds/KPgSVFDB6v3FTc2pC/openapi.json
