# Full Website Downloader (`schnellscrapers/full-website-downloader`) Actor

Download a public, server-rendered website as a ZIP with HTML, CSS, JavaScript, images, fonts, and other static assets. Crawl same-host links with configurable depth and limits. Best for landing pages, portfolios, blogs, and documentation; JavaScript-only apps are not rendered.

- **URL**: https://apify.com/schnellscrapers/full-website-downloader.md
- **Developed by:** [Nate Schnell](https://apify.com/schnellscrapers) (community)
- **Categories:** Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.99 / site archive

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/platform/actors/running/actors-in-store#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

### What does Full Website Downloader do?

Full Website Downloader creates one downloadable ZIP snapshot from a public website. It follows same-host links, saves HTML and referenced static assets, rewrites saved URLs for offline use, and returns the archive URL in the dataset. It is designed for small business sites, portfolios, landing pages, and static documentation.

### What data can you extract from a website?

- HTML pages — page source, same-host links, titles, and preserved URL structure
- Static assets — CSS, JavaScript, images, fonts, media, and other linked resources
- Archive summary — ZIP URL, status, page and asset counts, failed requests, size, and crawl timestamp
- Offline structure — relative links rewritten to the matching files inside the archive

### How to use Full Website Downloader

1. Open the actor and enter the public website URL.
2. Choose the crawl depth. Use `0` for the homepage only or `1` for the homepage and directly linked pages.
3. Keep Download static assets enabled for an offline snapshot, or disable it for HTML-only output.
4. Click Start. When the run finishes, open the ZIP archive URL in the dataset output.
5. Download the ZIP from the run results or use the dataset API in your workflow.

### How much does it cost?

Full Website Downloader costs **$3.99 per completed site archive**. One site event covers the capped crawl and one ZIP, whether the archive contains one page or the configured page limit. Apify platform usage is included in the actor price; the default caps keep ordinary public sites predictable. For the smallest bill, use `maxDepth: 0` or turn off static assets.

### Input

`startUrl` is required. `maxDepth`, `downloadAssets`, `includeExternalAssets`, `maxPages`, `maxAssets`, and byte/time limits control coverage and cost. The crawler uses direct HTTP requests and does not require a login, browser session, or proxy.

```json
{
  "startUrl": "https://example.org/",
  "maxDepth": 1,
  "downloadAssets": true,
  "includeExternalAssets": false,
  "maxPages": 50,
  "maxAssets": 250
}
```

### Output

The dataset contains one summary record. `archiveUrl` is the ZIP download URL; `status` is `succeeded` or `partial`, and the count fields show exactly what was included.

```json
{
  "website": "https://example.org/",
  "archiveUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/website-archive.zip",
  "archiveKey": "website-archive.zip",
  "status": "succeeded",
  "pagesDownloaded": 2,
  "assetsDownloaded": 5,
  "failedPages": 0,
  "failedAssets": 0,
  "archiveSizeBytes": 48231,
  "maxDepth": 1,
  "crawledAt": "2026-08-06T00:00:00.000Z"
}
```

### Integrations

Use the Apify API, webhooks, schedules, Make, Zapier, n8n, or a small Python/Node.js client to start a crawl and pass the archive URL to storage or deployment workflows.

### Related actors

- [Website Content Crawler](https://apify.com/apify/website-content-crawler) — extract clean text and Markdown for AI and RAG workflows.
- [Website Recovery Actor](https://apify.com/fiery_dream/website-recovery-actor) — recover a site with browser-oriented options and broader asset handling.
- [Bulk Image Downloader](https://apify.com/onescales/bulk-image-downloader) — download image-only ZIP packages from pages.

### FAQ

#### Does it render JavaScript?

No. It downloads the HTML returned by the server and the static resources linked from that HTML. For a JavaScript-only shell, the archive contains the shell and its linked files but does not execute the application.

#### Does it crawl another domain?

HTML pages are always limited to the start URL's hostname. External assets such as CDN CSS or fonts are included only when `includeExternalAssets` is enabled.

#### What happens when a page or asset fails?

The run keeps the successful files, records the failed-request counts, marks the output `partial`, and still provides the ZIP when at least the start page was downloaded.

#### How large can an archive be?

The default limits are 50 pages, 250 assets, 5 MB per asset, and 100 MB total downloaded bytes. Raise or lower them deliberately; the maximums are enforced to keep runs bounded.

# Actor input Schema

## `startUrl` (type: `string`):

Public website URL to archive. The crawler follows same-host links from this page.

## `maxDepth` (type: `integer`):

How many levels of same-host HTML links to follow. 0 downloads only the start page.

## `downloadAssets` (type: `boolean`):

Download same-host CSS, JavaScript, images, fonts, and other static resources referenced by crawled HTML.

## `includeExternalAssets` (type: `boolean`):

Also download assets hosted on other public domains. Disabled by default to keep archives focused and affordable.

## `maxPages` (type: `integer`):

Hard cap on HTML pages fetched for one archive. Set a lower value for a faster, smaller snapshot.

## `maxAssets` (type: `integer`):

Hard cap on static assets fetched for one archive.

## `maxAssetBytes` (type: `integer`):

Skip a single asset larger than this limit. This prevents unexpectedly large archives.

## `maxTotalBytes` (type: `integer`):

Stop downloading resources after this total byte budget is reached.

## `requestTimeoutSecs` (type: `integer`):

Maximum time to wait for one page or asset response.

## `dryRun` (type: `boolean`):

Crawl and build the archive without writing the ZIP or dataset record. Useful for validation.

## Actor input object example

```json
{
  "startUrl": "https://example.org/",
  "maxDepth": 1,
  "downloadAssets": true,
  "includeExternalAssets": false,
  "maxPages": 50,
  "maxAssets": 250,
  "maxAssetBytes": 5000000,
  "maxTotalBytes": 100000000,
  "requestTimeoutSecs": 20,
  "dryRun": false
}
```

# Actor output Schema

## `records` (type: `string`):

Dataset record with the ZIP URL, crawl status, page and asset counts, failures, and archive size.

# 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 = {
    "startUrl": "https://example.org/"
};

// Run the Actor and wait for it to finish
const run = await client.actor("schnellscrapers/full-website-downloader").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 = { "startUrl": "https://example.org/" }

# Run the Actor and wait for it to finish
run = client.actor("schnellscrapers/full-website-downloader").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrl": "https://example.org/"
}' |
apify call schnellscrapers/full-website-downloader --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=schnellscrapers/full-website-downloader",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/bNn2oS3aQHaPdqPOO/builds/DhkYrhvTCMy0EV997/openapi.json
