# Wayback Page Change Tracker: Archived Versions & Timeline (`transparent_meteorite/wayback-page-change-tracker`) Actor

See when any web page changed, from the Internet Archive Wayback Machine. One row per content version with date, days since the previous version, size change and archive links, or every archived URL of a domain. Summaries and new-only change alerts. No API key.

- **URL**: https://apify.com/transparent_meteorite/wayback-page-change-tracker.md
- **Developed by:** [Detroit Web Agent - Open Data](https://apify.com/transparent_meteorite) (community)
- **Categories:** SEO tools, Developer tools
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 snapshot returneds

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

## Wayback Page Change Tracker

Find out **when a web page changed** and see every version of it, straight from the Internet Archive Wayback Machine. Give it page URLs (a pricing page, terms of service, a competitor's homepage, a job board, a policy page) and it returns **one row per content version**: the capture date, the days since the previous version, how much the archived size changed, the content digest and direct Wayback links to view the page as it looked then.

It can also list **every archived URL of a domain** (an inventory of old and deleted pages), add a **summary row per URL** (first and latest version, median days between changes, longest quiet gap, versions per year), and run on a schedule to return **only new versions since the last run**, so you get change alerts without re-paying for history you already have.

No API key, no login, no proxy. The data comes from the public Wayback CDX index of the Internet Archive.

### What does Wayback Page Change Tracker do?

- **Page versions (default mode).** Identical captures are collapsed, so a page captured 900 times but changed 40 times gives you 40 rows, not 900. Each row is diffed against the version before it (time gap, size change in bytes and percent).
- **Latest or earliest.** Get the most recent N versions (default) or start from the beginning of a date window.
- **Size-change threshold.** Pages with dynamic tokens change on every capture. Set `minLengthChangePercent` (for example 2) to keep only versions whose archived size moved by at least that much. Skipped versions are not charged.
- **Change alerts.** Turn on `onlyNewSinceLastRun` and schedule the actor daily or weekly. It remembers the latest version per URL in a named key-value store and returns only newer versions, each still diffed against the last one you received.
- **Summary rows.** One extra row per URL with first and latest version dates, span, median days between changes, the longest gap and versions per year.
- **Archived URL inventory.** One row per unique URL the Wayback Machine holds for a domain (with subdomains), an exact host, or a path prefix such as `example.com/blog/`.
- **HTTP status filter.** 200-only for clean content versions, or all captures to see redirects and outages (301, 404, 5xx) over time.

### How it works

1. Each URL is cleaned (scheme, `www.` and fragments do not matter; pasted `web.archive.org/web/...` links are unwrapped).
2. The actor queries the Wayback CDX index with `collapse=digest` (versions) or `collapse=urlkey` (inventory), your date window and status filter, paging with resume keys.
3. Every row is validated before it is pushed. URLs that carry an email address, token, session id, password or API key in the URL are dropped and never charged.
4. You are charged only for rows that reach your dataset.

Requests are spaced about one second apart to respect the Internet Archive, with retries on 429 and 5xx answers.

### Input

| Field | What it does | Default |
|---|---|---|
| `urls` | Page URLs or domains (up to 100). | `["apify.com/pricing"]` |
| `mode` | `versions` (content changes) or `urlInventory` (every archived URL of a site). | `versions` |
| `matchType` | Inventory scope: `domain` (with subdomains), `host`, or `prefix`. | `domain` |
| `dateFrom`, `dateTo` | Optional window: `YYYY`, `YYYY-MM` or `YYYY-MM-DD`. | none |
| `order` | `newest` = the most recent versions, `oldest` = from the start of the window. | `newest` |
| `statusFilter` | `ok` = 200 captures only, `all` = include redirects and errors. | `ok` |
| `minLengthChangePercent` | Skip versions whose size changed less than this percent. | `0` |
| `maxRowsPerUrl` | Cap per URL. | `100` |
| `maxResults` | Cap across all URLs (charged rows). | `25` |
| `includeSummary` | Add one summary row per URL. | `false` |
| `onlyNewSinceLastRun` | Return only versions newer than the last run. | `false` |
| `stateStoreName` | Key-value store that remembers the last version per URL. | `wayback-page-change-tracker-state` |

#### Input example

```json
{
  "urls": ["apify.com/pricing", "stripe.com/pricing"],
  "order": "newest",
  "maxRowsPerUrl": 15,
  "maxResults": 30,
  "includeSummary": true
}
```

Monitoring example (schedule it weekly):

```json
{
  "urls": ["competitor.com/pricing", "competitor.com/terms"],
  "onlyNewSinceLastRun": true,
  "minLengthChangePercent": 2,
  "stateStoreName": "competitor-watch"
}
```

### Output

One JSON object per row. Download as JSON, CSV, Excel or XML, or read it through the Apify API. The dataset has three views: **Page versions**, **Archived URLs** and **Target summaries**.

#### Sample output (page version)

```json
{
  "type": "page_version",
  "target": "apify.com/pricing",
  "url": "https://apify.com/pricing",
  "versionNumber": 2,
  "capturedAt": "2026-10-18T08:04:19Z",
  "waybackTimestamp": "20261018080419",
  "archiveUrl": "https://web.archive.org/web/20261018080419/https://apify.com/pricing",
  "rawArchiveUrl": "https://web.archive.org/web/20261018080419id_/https://apify.com/pricing",
  "statusCode": 200,
  "mimeType": "text/html",
  "contentDigest": "…",
  "lengthBytes": 66650,
  "previousCapturedAt": "2026-10-17T22:43:48Z",
  "daysSincePreviousVersion": 0.4,
  "lengthChangeBytes": 128,
  "lengthChangePercent": 0.2,
  "changeScore": 0,
  "isFirstVersionInWindow": false,
  "scrapedAt": "2026-11-06T06:02:47.494Z"
}
```

#### Sample output table

| target | versionNumber | capturedAt | statusCode | lengthBytes | lengthChangePercent | daysSincePreviousVersion | archiveUrl |
|---|---|---|---|---|---|---|---|
| apify.com/pricing | 1 | 2026-10-17T22:43:48Z | 200 | 66522 | 0.7 | 0.7 | web.archive.org/web/20261017224348/... |
| apify.com/pricing | 2 | 2026-10-18T08:04:19Z | 200 | 66650 | 0.2 | 0.4 | web.archive.org/web/20261018080419/... |

#### Output fields

| Field | Meaning |
|---|---|
| `type` | `page_version`, `archived_url` or `target_summary` |
| `target` | The URL or domain you asked for |
| `url` | The exact URL that was captured |
| `versionNumber` | Order of the version within this run's window (1 = earliest returned) |
| `capturedAt`, `waybackTimestamp` | Capture time (ISO 8601 UTC and the 14-digit Wayback form) |
| `archiveUrl`, `rawArchiveUrl` | View the capture in the Wayback Machine, or the raw captured bytes (`id_`) |
| `statusCode`, `mimeType` | HTTP status and content type at capture time |
| `contentDigest` | SHA-1 digest of the captured content; a new digest means the bytes changed |
| `lengthBytes` | Archived record size (compressed) |
| `previousCapturedAt`, `daysSincePreviousVersion` | The version before this one and the gap in days |
| `lengthChangeBytes`, `lengthChangePercent` | Size change vs the previous version |
| `changeScore` | 0-100 change size (absolute size change %, capped at 100), handy for ranking or alerting on big edits |
| `isFirstVersionInWindow` | True when there was no earlier version to compare against |
| Summary fields | `versionsFound`, `firstVersionAt`, `latestVersionAt`, `spanDays`, `medianDaysBetweenChanges`, `longestGapDays`, `longestGapFrom`, `longestGapTo`, `versionsPerYear`, `latestArchiveUrl`, `truncated` |

Missing values are `null`, never empty strings.

### Pricing

Pay per event: you pay only for rows delivered to your dataset.

| Event | Price |
|---|---|
| Actor start | $0.00005 per run |
| Snapshot returned (one page version or one archived URL) | $0.0005 ($0.50 per 1,000) |
| Target summary returned (optional) | $0.002 per URL |

**Worked cost example:** a weekly watch of 20 competitor pages with `includeSummary` on, where each page has 10 new versions in the window: 200 versions x $0.0005 = $0.10, plus 20 summaries x $0.002 = $0.04, plus $0.00005 start = **about $0.14 per run**. With `onlyNewSinceLastRun`, later runs charge only for versions you have not received yet, so a quiet week costs close to nothing.

Identical captures, versions below your size-change threshold, invalid rows and versions already delivered in a monitoring run are never charged. Set **Maximum cost per run** in the run options to cap spend; the actor stops cleanly when it is reached.

### Use cases

- **Competitor pricing and plan tracking:** see every date a rival's pricing page changed, then open the archive links side by side to see what moved.
- **Terms of service and privacy policy audits:** list each version of a policy page with dates for compliance files, disputes or research.
- **SEO and site migrations:** inventory every archived URL of a domain to rebuild redirect maps and recover deleted pages that still have backlinks.
- **Expired domain due diligence:** check how often a domain's homepage changed and when it went quiet before you buy it.
- **Journalism and OSINT:** document when a statement, product page or job posting was edited or removed, with a citable Wayback link per version.
- **Scheduled change alerts:** run weekly with `onlyNewSinceLastRun` and send new rows to Slack, email, Google Sheets or an n8n/Make/Zapier workflow.

### Related actors

- [Domain Intelligence Lookup](https://apify.com/transparent_meteorite/domain-intelligence-lookup): DNS, registration and hosting facts for a domain.
- [SSL Certificate Subdomain Finder](https://apify.com/transparent_meteorite/ssl-certificate-subdomain-finder): subdomains from certificate transparency logs, a good companion to the archived URL inventory.
- [Company Enrichment by Domain](https://apify.com/transparent_meteorite/company-enrichment-by-domain): company facts for the domains you track.

### Use with the API, n8n, Make, Zapier or AI agents

**API** (one call, returns the rows as JSON):

```bash
curl -X POST "https://api.apify.com/v2/acts/transparent_meteorite~wayback-page-change-tracker/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urls":["apify.com/pricing","stripe.com/pricing"],"order":"newest","maxRowsPerUrl":13,"maxResults":25,"includeSummary":true}'
```

The call waits up to 5 minutes. For bigger inputs, start the run with `/runs` instead and read the dataset when it finishes.

**Python**

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("transparent_meteorite/wayback-page-change-tracker").call(run_input={"urls": ["apify.com/pricing", "stripe.com/pricing"], "order": "newest", "maxRowsPerUrl": 13, "maxResults": 25, "includeSummary": True})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row)
```

- **n8n, Make, Zapier:** use the Apify app's "Run Actor" step with actor `transparent_meteorite/wayback-page-change-tracker`, paste the input JSON, then map the dataset items to your sheet or CRM.
- **Clay:** add an HTTP API column that calls the run-sync endpoint above.
- **Schedules:** in Apify Console, Schedules, run it daily or weekly with the same input for a steady feed.
- **AI agents (MCP):** connect the Apify MCP server at `https://mcp.apify.com?tools=transparent_meteorite/wayback-page-change-tracker` to Claude, Cursor or any MCP client, and your agent can run Wayback Page Change Tracker on request.

### FAQ

**Does it download the archived pages?**
No. It reads the Wayback CDX index (capture metadata). Every row includes `archiveUrl` and `rawArchiveUrl` so you can open or fetch any version yourself. This keeps runs fast and cheap.

**What counts as a change?**
A capture whose content digest differs from the capture right before it. Pages with rotating tokens, timestamps or ads can change on every capture; use `minLengthChangePercent` to keep only meaningful size changes.

**Do http/https and www matter?**
No. The Wayback index normalizes them, so `example.com/pricing` covers all variants. The `url` field shows exactly what was captured.

**Can I monitor pages over time?**
Yes. Turn on `onlyNewSinceLastRun`, pick a `stateStoreName` per watch list and schedule the actor. Each run returns only versions newer than the last one delivered.

**Why did a URL return nothing?**
Either the Wayback Machine has no 200 captures for it in your window (try `statusFilter: all` or remove the dates), or the site owner has excluded it from the archive. The run log and the OUTPUT record list these URLs.

**Do I need an API key or a proxy?**
No. The CDX index is public and is called directly.

### Limitations

- Coverage is whatever the Internet Archive captured. Small or new sites may have few captures; crawl frequency varies by site and over time.
- Changes between two captures are invisible; the capture dates bound when a change happened, they do not pinpoint it.
- `lengthBytes` is the compressed archive record size, a rough signal of how much changed, not a text diff.
- Archived URL inventory queries on large domains are heavy for the CDX server and can take 30 to 90 seconds per page or time out; the actor retries and then reports the error without charging. Use `host` or `prefix` scope to narrow large sites.
- Sites excluded from the Wayback Machine return no rows.
- URLs carrying emails, tokens, session ids or passwords in the URL are dropped on purpose.

### Data source and terms

Capture metadata comes from the Internet Archive's public Wayback CDX server. The Internet Archive is a non-profit; please use reasonable volumes. This actor is independent and is not affiliated with or endorsed by the Internet Archive.

# Actor input Schema

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

Pages to track, for example example.com/pricing or https://www.example.com/terms. Scheme and www do not matter (the Wayback index ignores them). In Archived URL inventory mode, give domains, for example example.com. Up to 100 per run.

## `mode` (type: `string`):

Page versions = one row each time the archived content of a page changed (identical captures are collapsed), with time since the previous version and size change. Archived URL inventory = one row per unique URL the Wayback Machine holds for a domain, host or path prefix.

## `matchType` (type: `string`):

Inventory mode only: which URLs to list.

## `dateFrom` (type: `string`):

Optional. YYYY, YYYY-MM or YYYY-MM-DD. Only captures on or after this date.

## `dateTo` (type: `string`):

Optional. YYYY, YYYY-MM or YYYY-MM-DD. Only captures on or before this date.

## `order` (type: `string`):

Versions mode: start from the beginning of the window, or return the most recent N versions (still listed oldest to newest).

## `statusFilter` (type: `string`):

200 only gives clean content versions. All includes redirects and error captures, useful to see when a page went down or moved.

## `minLengthChangePercent` (type: `number`):

Versions mode: skip versions whose archived size changed less than this percent vs the last delivered version (filters out tiny dynamic changes such as tokens or timestamps). Skipped versions are not charged. 0 = every content change.

## `maxRowsPerUrl` (type: `integer`):

Cap per target (versions or archived URLs).

## `maxResults` (type: `integer`):

Total cap across all targets. Each row is one charged result; summaries are charged separately.

## `includeSummary` (type: `boolean`):

Versions mode: one extra row per target with first/latest version, median days between changes, longest gap and versions per year. Charged as a separate summary event.

## `onlyNewSinceLastRun` (type: `boolean`):

Versions mode: remember the latest version delivered per URL in a named key-value store and return only newer versions next time. Schedule it daily or weekly to get change alerts.

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

Named key-value store that holds the last delivered version per URL when monitoring. Use a different name per watch list.

## `maxApiRequests` (type: `integer`):

Safety cap on requests to the Wayback CDX server.

## `maxRunSeconds` (type: `integer`):

The run stops cleanly (keeping delivered rows) after this many seconds.

## Actor input object example

```json
{
  "urls": [
    "apify.com/pricing"
  ],
  "mode": "versions",
  "matchType": "domain",
  "order": "newest",
  "statusFilter": "ok",
  "minLengthChangePercent": 0,
  "maxRowsPerUrl": 100,
  "maxResults": 25,
  "includeSummary": false,
  "onlyNewSinceLastRun": false,
  "stateStoreName": "wayback-page-change-tracker-state",
  "maxApiRequests": 200,
  "maxRunSeconds": 600
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `inventory` (type: `string`):

No description

## `summaries` (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 = {
    "urls": [
        "apify.com/pricing"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("transparent_meteorite/wayback-page-change-tracker").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": ["apify.com/pricing"] }

# Run the Actor and wait for it to finish
run = client.actor("transparent_meteorite/wayback-page-change-tracker").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": [
    "apify.com/pricing"
  ]
}' |
apify call transparent_meteorite/wayback-page-change-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,transparent_meteorite/wayback-page-change-tracker"
        }
    }
}
```

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/CTZIpiUtkdeV3MeTz/builds/f1hdx3sO9gTTP3GvA/openapi.json
