# Websites Archiver (Wayback Machine) (`web.harvester/websites-archiver`) Actor

Effortlessly archive any website with our Automated Website Archiving Tool. It leverages the power of the Wayback Machine at web.archive.org to ensure your sites are preserved for future reference.

- **URL**: https://apify.com/web.harvester/websites-archiver.md
- **Developed by:** [Web Harvester](https://apify.com/web.harvester) (community)
- **Categories:** Automation, Integrations
- **Features:** Full permissions
- **Stats:** 101 total users, 1 monthly users, 100.0% runs succeeded, 3 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.80 / 1,000 archived urls

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Websites Archiver (Wayback Machine)

Save any list of web pages to the [Internet Archive's Wayback Machine](https://web.archive.org/) and get a permanent snapshot link for each one. It works like clicking **Save Page Now** on web.archive.org, but for a whole list of URLs in one run, and returns the results as a dataset you can download or connect to other tools.

### What does Websites Archiver do?

For every URL you give it, the Actor:

1. Asks the Wayback Machine to capture the page (Save Page Now).
2. Waits until the capture is finished.
3. Returns the snapshot link (`https://web.archive.org/web/<timestamp>/<url>`), the capture time, the HTTP status of the page and how many resources were saved.

If the Wayback Machine refuses a URL (unknown host, excluded site, crawler trap), the result says why.

### Why archive pages in the Wayback Machine?

- **Evidence and compliance**: keep a timestamped, third-party copy of terms of service, pricing pages, ads or claims.
- **Link rot protection**: archive the pages your articles, docs or research cite, so the links keep working.
- **Monitoring**: schedule the Actor to snapshot competitor or product pages every day or week.
- **Before a migration or redesign**: preserve the old version of your site.

### How to archive websites

1. Click **Try for free**.
2. Add the pages in **URLs to archive**. You can type them, paste a list, or link a text file that contains the URLs.
3. Click **Start**.
4. When the run finishes, open the **Output** tab and download the results as JSON, CSV, Excel or HTML.

Each URL is archived as one page. Links on the page are not followed. To archive a whole site, add all its page URLs (for example from its sitemap).

### Input

| Field | Default | Description |
|-------|---------|-------------|
| **URLs to archive** (`startUrls`) | required | Pages to save. Add `{ "url": "..." }` items, or `{ "requestsFromUrl": "..." }` pointing to a text file that contains URLs. Only `http(s)` URLs are read from the file; other text is skipped. Duplicates are archived once. |
| **Fast mode** (`fastArchiveMode`) | `false` | Only submit the URLs and return their job IDs, without waiting for the result. Results then have no snapshot link and archiving is not confirmed. |
| **Save error pages** (`archiveErrorPages`) | `true` | Also save pages that answer with HTTP 4xx/5xx, such as 404. When off, those URLs are reported as failed. |
| **Save list of archived resources** (`storeArchivedResources`) | `false` | Add the URLs of all saved resources (HTML, scripts, styles, images) to each result. Ignored in fast mode. |
| **Proxy configuration** (`proxyConfiguration`) | Apify Proxy (datacenter) | Keep the default. The Wayback Machine allows about 3 captures at a time per IP address, so a proxy makes runs faster and more reliable. See [Good to know](#good-to-know). |

Example input:

```json
{
    "startUrls": [
        { "url": "https://crawlee.dev" },
        { "url": "https://docs.apify.com/platform" },
        { "requestsFromUrl": "https://example.com/urls-to-archive.txt" }
    ],
    "archiveErrorPages": true,
    "storeArchivedResources": false,
    "proxyConfiguration": { "useApifyProxy": true }
}
```

### Output

One result per URL. Example of an archived page:

```json
{
    "url": "https://docs.apify.com/platform/storage/dataset",
    "status": "archived",
    "archived": true,
    "archivedUrl": "https://web.archive.org/web/20261003151218/https://docs.apify.com/storage/dataset",
    "archivedAt": "2026-10-03T15:12:18.000Z",
    "capturedUrl": "https://docs.apify.com/storage/dataset",
    "httpStatus": 200,
    "jobId": "spn2-8c01349fdb95d9bc065af32743f2d4ebc9d3343d",
    "archivedResourcesCount": 127,
    "outlinksCount": 103,
    "note": null,
    "errorCode": null
}
```

Example of a URL the Wayback Machine refused:

```json
{
    "url": "https://nonexistent-domain-qq55443.com/",
    "status": "failed",
    "archived": false,
    "archivedUrl": null,
    "archivedAt": null,
    "capturedUrl": null,
    "httpStatus": null,
    "jobId": null,
    "archivedResourcesCount": null,
    "outlinksCount": null,
    "note": "Cannot resolve host nonexistent-domain-qq55443.com. If the site is online, it may be blocking access from our service.",
    "errorCode": "rejected"
}
```

| Field | Description |
|-------|-------------|
| `url` | URL from your input. |
| `status` | `archived`: snapshot confirmed. `submitted`: capture started but not confirmed (fast mode, or still running after 5 minutes). `failed`: not archived. |
| `archived` | `true` only when the snapshot is confirmed. |
| `archivedUrl` | Permanent Wayback Machine link. |
| `archivedAt` | Capture time from the Wayback Machine (UTC). |
| `capturedUrl` | URL that was actually captured, after redirects. |
| `httpStatus` | HTTP status the page returned to the Wayback Machine. |
| `jobId` | Save Page Now job ID. |
| `archivedResourcesCount` | Number of saved resources (HTML, scripts, styles, images). |
| `outlinksCount` | Number of links found on the page. |
| `note` | Message from the Wayback Machine, such as why archiving failed or that a recent snapshot was reused. |
| `errorCode` | Short reason code when the URL was not archived or not confirmed. See the table below. |
| `archivedResources` | List of saved resource URLs, only with **Save list of archived resources**. |

The **Overview** view shows the snapshot links. The **Failed** view lists the URLs that were not archived and why.

#### Error codes

| `errorCode` | `status` | Meaning |
|-------------|----------|---------|
| `rejected` | `failed` | The Wayback Machine refused the URL: unknown host, site excluded from the archive, or a crawler trap. `note` has its exact message. |
| `rate-limited` | `failed` | The Wayback Machine kept refusing new captures after all retries. Run the URL again later or use a proxy. |
| `capture-timeout` | `submitted` | The capture was still running after 5 minutes. It may still finish later. Check the page's capture list (see below). |
| `not-found`, `service-unavailable`, `blocked-url`, … | `failed` | Codes from the Wayback Machine. Usually the error the page itself returned when **Save error pages** is off. `note` has the details. |
| `job-failed`, `submit-http-503`, `unexpected-status-response`, … | `failed` | A temporary Wayback Machine problem that persisted through all 8 retries. Run the URL again later. |
| `url-list-failed` | `failed` | A linked URL file could not be downloaded or contains no URLs. The other URLs are still archived. `url` is the file's address. |
| `invalid-url` | `failed` | An input entry is not an `http(s)` URL (for example `ftp://…`). |
| `request-failed` | `failed` | An unexpected network error after all retries. |

### Good to know

- **Recent snapshots are reused.** If the page was captured shortly before, the Wayback Machine returns that snapshot instead of making a new one, with a note such as "The same snapshot had been made 2 minutes ago. You can make new capture of this URL after 1 hour." The result then has that note, and `archivedAt` is the time of the earlier capture.
- **Speed.** A capture usually takes 15–30 seconds. With the default proxy the Actor archives up to 10 URLs in parallel. In our tests, runs of 10–12 URLs took 2–3.5 minutes.
- **Proxy.** The Wayback Machine allows only about 3 captures at a time per IP address. With a proxy, a rate-limited URL is retried right away from a new IP. Without a proxy, the Actor archives 3 URLs at a time and waits a minute after each rate limit, so runs are slower. Residential proxy also works but costs about 3× more and is not needed.
- **Retries.** Rate limits and temporary Wayback Machine failures are retried automatically, up to 8 times per URL. Failures caused by the page itself (unknown host, excluded site) are reported right away.
- **Checking a page's captures later.** Open `https://web.archive.org/web/*/<your URL>` to see every snapshot of a page, for example after fast mode or a `capture-timeout`. If the page redirects, look up the `capturedUrl` instead.
- **Some sites cannot be archived.** Site owners can exclude their site from the Wayback Machine, and some sites block its crawler.

### How much does it cost?

The Actor sends plain HTTP requests and runs without a browser on 256 MB of memory, so platform usage is very low. Most of the run time is spent waiting for the Wayback Machine to finish each capture. In our tests, archiving 10–12 URLs used about $0.003–0.004 of platform usage with the default datacenter proxy, and about $0.011 with residential proxy.

### Integrations and API

- **Schedule it**: use [Apify Schedules](https://docs.apify.com/platform/schedules) to snapshot the same pages every day, week or month.
- **Use the results elsewhere**: send them to Google Sheets, Slack, Zapier, Make or webhooks with [Apify integrations](https://docs.apify.com/platform/integrations).
- **Run it from code**: start the Actor and read its dataset with the [Apify API](https://docs.apify.com/api/v2) or the Apify JavaScript and Python clients.

### Is it legal?

The Actor only uses the public Save Page Now service of the Internet Archive, the same as clicking the button on web.archive.org. Use it responsibly: the Wayback Machine is a free, non-profit service. Don't submit the same pages over and over, and respect the [Internet Archive's Terms of Use](https://archive.org/about/terms.php).

### Feedback

Found a bug or missing a feature? Open an issue in the **Issues** tab.

# Changelog

This Actor's version history is a separate document: https://apify.com/web.harvester/websites-archiver/changelog.md

# Actor input Schema

## `startUrls` (type: `array`):

Web pages to save in the Wayback Machine. Add URLs one by one, paste a list, or link a text file that contains the URLs. Each URL is saved as one page: links on it are not followed. Duplicate URLs are archived once.

## `fastArchiveMode` (type: `boolean`):

Only submit each URL to the Wayback Machine and return its Save Page Now job ID, without waiting for the capture to finish. Results then have no snapshot link, and the Actor does not confirm that archiving succeeded. Leave this off to get a snapshot link for every URL.

## `archiveErrorPages` (type: `boolean`):

Also save pages that answer with an error status, such as 404 Not Found or 500 Internal Server Error. When off, those URLs are reported as failed with the page's error in the result.

## `storeArchivedResources` (type: `boolean`):

Add the URLs of every saved resource (HTML, scripts, styles, images) to each result. Useful for checking that a page was archived completely. Ignored in fast mode.

## `proxyConfiguration` (type: `object`):

Recommended: keep the default Apify Proxy (datacenter). The Wayback Machine allows only about 3 captures at a time per IP address. With a proxy, the Actor archives up to 10 URLs in parallel and retries rate-limited URLs from a new IP. Without a proxy, it archives 3 at a time and waits a minute after each rate limit, so runs are slower. Residential proxy also works but costs more and is not needed.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://crawlee.dev"
    },
    {
      "url": "https://docs.apify.com/platform"
    }
  ],
  "fastArchiveMode": false,
  "archiveErrorPages": true,
  "storeArchivedResources": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# 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 = {
    "startUrls": [
        {
            "url": "https://crawlee.dev"
        },
        {
            "url": "https://docs.apify.com/platform"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("web.harvester/websites-archiver").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 = {
    "startUrls": [
        { "url": "https://crawlee.dev" },
        { "url": "https://docs.apify.com/platform" },
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("web.harvester/websites-archiver").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 '{
  "startUrls": [
    {
      "url": "https://crawlee.dev"
    },
    {
      "url": "https://docs.apify.com/platform"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call web.harvester/websites-archiver --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,web.harvester/websites-archiver"
        }
    }
}
```

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/TZZn64EflAv7ZKi7P/builds/NVS7ud98BUAZfMF2P/openapi.json
