# Website Screenshot & PDF: Full-Page, Mobile, Change Alerts (`nat-labs/website-screenshot-scraper`) Actor

Full-page website screenshots and PDFs in PNG, JPEG, WebP. Lazy-load scrolling, sticky headers fixed, cookie banners dismissed, mobile/tablet/desktop in one run, element and clip capture, visual change alerts with diff %. Same input as apify/screenshot-url. Failed pages are free.

- **URL**: https://apify.com/nat-labs/website-screenshot-scraper.md
- **Developed by:** [Nat | Data Tools](https://apify.com/nat-labs) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 captures

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
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

## Website Screenshot & PDF: Full-Page, Mobile, Change Alerts

Turn any list of URLs into **full-page screenshots (PNG, JPEG, WebP) and PDFs**. Desktop, laptop, tablet and mobile in one run. Lazy images are scrolled into view, cookie banners are clicked away, sticky headers appear once, emoji and CJK text render. Need monitoring? Schedule it and get **only the pages that visually changed**, with the diff % and a highlighted diff image.

**Failed pages cost nothing.** Timeouts, bot walls, robots.txt skips and 4xx/5xx error pages are never charged.

### Why this screenshot Actor

| | This Actor | apify/screenshot-url and most screenshot actors |
|---|---|---|
| Full page | Really full: lazy-load scrolling on by default, image/font waits, app-shell pages unrolled | Often only the first screen or blank placeholders ("only screenshots above the fold") |
| Sticky headers & chat bubbles | Header shown once at the top, floating widgets removed (`stickyElements`) | Header repeated or floating over content (open issue since 2024) |
| Cookie banners | Clicked away (OneTrust, Cookiebot, Didomi, Quantcast, Sourcepoint, Usercentrics, …) | Banner covers the page |
| Size control | `maxHeight`, viewport height, element `selector`, `clip` rectangle | Width only ("Cannot set height of the image") |
| Devices | desktop, laptop, 1080p, 2K, mobile, Android, tablet, any Playwright device, or `"1366x768@2"`, several per run | One width per run |
| Formats | PNG, JPEG, WebP and PDF from **one page load** | PNG or PDF |
| Speed & hangs | Per-page hard deadline + one retry; a run never hangs on one page | Runs stuck for minutes ("API gets stuck for a very long time") |
| Price | **$3 / 1,000 files, all-inclusive**; failures free | Free actor but you pay compute; reviews report up to $0.04 per screenshot |
| Monitoring | **Only changed pages**, diff %, changed region, diff image | Re-download everything |
| Fonts | Colour emoji + Chinese/Japanese/Korean fonts installed | Emoji as boxes |
| Page metadata | HTTP status, final URL after redirects, title, description, language, timings | URL + image link only |
| AI agents | Lenient input: `"example.com"`, `"mobile"`, `"jpg"`; optional base64 output | Strict input |
| Compatibility | Accepts the **same input as apify/screenshot-url** and returns `startUrl`, `url`, `screenshotUrl`, `screenshotKey` | — |

### What you can do

- **Website archives and compliance evidence**: full-page PNG + PDF of each page, timestamped into a named store.
- **Competitor and pricing monitoring**: schedule daily, get alerted only when a page changes (with what changed highlighted).
- **QA and responsive checks**: every page on desktop, tablet and mobile in one run, from a sitemap.
- **SEO and marketing**: thumbnails, social-card crops (`clip`), landing-page galleries.
- **AI agents**: give an LLM a picture of a page (`includeBase64`) through Apify's AI integrations.
- **Your own stack**: run it from the Apify API, the Python or JavaScript client, Make, Zapier, n8n, Google Sheets, Slack, webhooks or a schedule; export JSON, CSV or Excel.

### Quick start

#### 1. Full-page screenshots of a few sites

```json
{ "urls": [{ "url": "https://apify.com" }, { "url": "https://en.wikipedia.org/wiki/Web_scraping" }] }
```

#### 2. Desktop + mobile, PNG and PDF

```json
{
    "urls": [{ "url": "https://www.bbc.com/news" }],
    "devices": ["desktop", "mobile"],
    "formats": ["png", "pdf"]
}
```

→ 4 files (2 devices × 2 formats) = 4 captures.

#### 3. Just the top of the page, or one element

```json
{ "urls": [{ "url": "https://stripe.com" }], "maxHeight": 2000, "formats": ["jpeg"], "quality": 75 }
```

```json
{ "urls": [{ "url": "https://www.python.org" }], "selector": "#content", "deviceScaleFactor": 2 }
```

#### 4. Every page of a sitemap

```json
{ "sitemapUrls": ["https://crawlee.dev/sitemap.xml"], "maxUrls": 200, "formats": ["webp"] }
```

For 50+ pages, give the run **4 GB memory** (two pages render in parallel; it is ~25 % faster per page).

#### 5. Visual change monitoring (schedule it)

```json
{
    "urls": [{ "url": "https://competitor.example/pricing" }],
    "onlyChanges": true,
    "monitorName": "competitor-pricing",
    "changeThresholdPercent": "1",
    "hideSelectors": [".rotating-banner"]
}
```

The first run stores the baseline. Every later run delivers the page **only if at least 1 % of it changed**, with `change.diffPercent`, the changed region and a highlighted `change.diffImageUrl`. Unchanged pages cost a cheaper `monitor-check`. Connect a Slack, email or webhook integration to the run to get alerts.

#### Migrating from apify/screenshot-url

Paste your existing input. `urls`, `format`, `waitUntil` (including `networkidle0` / `networkidle2`), `delay`, `viewportWidth`, `scrollToBottom`, `delayAfterScrolling`, `waitUntilNetworkIdleAfterScroll`, `waitUntilNetworkIdleAfterScrollTimeout`, `proxy` and `selectorsToHide` work as before, and each dataset row keeps `startUrl`, `url`, `screenshotUrl` and `screenshotKey`.

### Output

One dataset row per URL and device; the files are in the run's key-value store (or the named store you choose) with public links.

```json
{
    "startUrl": "https://apify.com",
    "url": "https://apify.com/",
    "device": "desktop",
    "viewport": { "width": 1280, "height": 800, "deviceScaleFactor": 1, "isMobile": false },
    "fullPage": true,
    "status": "ok",
    "httpStatus": 200,
    "title": "Apify: Full-stack web scraping and data extraction platform",
    "description": "Cloud platform for web scraping, browser automation, AI agents, and data for AI…",
    "lang": "en",
    "screenshotUrl": "https://api.apify.com/v2/key-value-stores/axdGeKUanIf75yrfA/records/screenshot_apify_com_desktop_b02971732f.png?signature=…",
    "screenshotKey": "screenshot_apify_com_desktop_b02971732f.png",
    "format": "png",
    "pdfUrl": null,
    "files": [
        { "format": "png", "key": "screenshot_apify_com_desktop_b02971732f.png", "url": "https://api.apify.com/v2/key-value-stores/…", "bytes": 1227153, "width": 1280, "height": 10052 }
    ],
    "pageHeight": 10052,
    "truncated": false,
    "cookieBannerClicked": "#onetrust-accept-btn-handler",
    "transferKb": 5481,
    "blockedRequests": 28,
    "timings": { "navigationMs": 887, "loadMs": 1103, "scrollMs": 2576, "readyMs": 4685, "screenshotMs": 299, "totalMs": 5312 },
    "warnings": [],
    "charged": true,
    "capturedAt": "2026-10-17T10:13:01.000Z"
}
```

With monitoring, changed pages also carry:

```json
"change": {
    "status": "changed",
    "diffPercent": 14.7,
    "changedBox": { "x": 0, "y": 220, "width": 1280, "height": 660 },
    "heightChangePx": 71,
    "previousCapturedAt": "2026-10-16T09:41:12.997Z",
    "previousScreenshotUrl": "https://api.apify.com/v2/key-value-stores/…",
    "diffImageUrl": "https://api.apify.com/v2/key-value-stores/…_diff.jpg"
}
```

Pages that could not be captured are listed too (free), with `status` `failed`, `blocked` (bot wall, with `blockedBy`) or `skipped` (robots.txt, invalid or private URL, element not found), plus `errorReason` and `error`. Run totals and every failure are in the `STATISTICS` record.

### Pricing

Pay per event. **Platform usage is included**: no start fee, no compute bill on top.

| Event | What it is | Price |
|---|---|---|
| Capture | One delivered file: PNG, JPEG, WebP or PDF | **$3.00 / 1,000** ($0.003) |
| Monitor check | Monitoring: page rendered and compared, nothing changed, nothing delivered | $2.20 / 1,000 |
| Residential MB | Only if you choose Apify RESIDENTIAL proxy: per started MB of page traffic | $0.012 / MB |

Lower rates apply automatically on higher Apify plans (captures down to $2.50 / 1,000). **Never charged:** failed or timed-out pages, bot walls, robots.txt skips, invalid URLs, HTTP 4xx/5xx error pages (delivered free), diff images, base64 copies.

Examples: 1,000 URLs, full-page PNG = **$3**. 100 URLs × desktop + mobile × PNG + PDF = 400 files = **$1.20**. Daily monitoring of 20 pricing pages for a month ≈ 600 checks ≈ **$1.32**, plus $0.003 for each day a page actually changed.

The Actor checks your run's **maximum cost** before each page and stops cleanly when it is reached.

**Free Apify plan:** up to 25 pages (URL × device) per run (a limit set by the developer, not by Apify). Any paid plan removes it.

### Good to know

- **No proxy by default.** The browser connects directly from Apify's servers, which works for the vast majority of public sites and keeps captures fast and cheap. Use `proxyConfiguration` for other countries (Apify datacenter proxy) or residential IPs (billed per MB).
- **Bot walls are not bypassed.** Sites behind Cloudflare challenges, DataDome, PerimeterX, Akamai or CAPTCHAs are reported as `blocked` and not charged. The Actor never solves CAPTCHAs or fakes challenge tokens.
- **robots.txt is respected** by default. Turn `respectRobotsTxt` off only for sites you own or are allowed to capture.
- **No logins.** Pages behind a login are out of scope; the Actor does not accept cookies or credentials.
- **Very long pages** are cut at `maxPageHeight` (20,000 px by default) and flagged `truncated`. WebP files are limited to 16,383 px by the format itself; use PNG or JPEG for longer pages.
- **Video and audio are not loaded** by default (a screenshot cannot show them, and they slow pages down). Set `blockResources` to `[]` to load everything.
- **Memory:** 2 GB (default) renders one page at a time and is the cheapest for small runs; 4 GB renders two at once and is best for large lists.
- Files in the run's default store follow your Apify data retention. Set `keyValueStoreName` to keep a permanent, timestamped archive.

### Is it legal to take website screenshots?

Capturing a public web page the way a browser displays it is a common, long-established practice (archiving, QA, monitoring, evidence). This Actor only opens pages anyone can see without logging in, respects robots.txt and does not bypass bot protection. Screenshots can contain copyrighted material and personal data (for example names in a news article): they are stored in **your** Apify storage and you are responsible for how you use them under copyright law, the site's terms and data-protection law such as the GDPR. Check a site's terms before capturing it at scale; for commercial redistribution, consult a lawyer.

### FAQ

**How is this different from ScreenshotOne, Urlbox or ApiFlash?** Similar features (full page, devices, cookie banners, PDF), no monthly plan: you pay $3 per 1,000 files only when you use it, failures are free, and visual change monitoring is built in.

**Can I call it for one URL from my app?** Yes, through the Apify API (run-sync endpoint) or the client libraries; a single page usually takes 5–15 seconds including browser start.

**Can I use it from Claude, ChatGPT or Cursor?** Yes, through Apify's AI integrations. Set `includeBase64: true` if the agent cannot download URLs.

**Why is one page slower than another?** Heavy JavaScript sites (animated hero sections, big news front pages) take 20–40 s on a shared cloud CPU; simple pages take 2–5 s. `timings` in each row shows where the time went.

**What if a site changes its cookie banner?** The page is still captured; the banner may be visible. Add its selector to `hideSelectors` and open an issue so it gets added for everyone.

# Actor input Schema

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

Pages to capture. Full URLs or bare domains ("example.com"). Several URLs pasted into one line separated by spaces or new lines work too.

## `sitemapUrls` (type: `array`):

Capture every page listed in these sitemap.xml files (sitemap indexes and .xml.gz supported), up to "Max URLs".

## `maxUrls` (type: `integer`):

Upper limit of URLs per run (each URL is captured once per device). 0 = 10,000.

## `devices` (type: `array`):

One capture per device for every URL. Presets: desktop (1280×800), laptop (1440×900), desktop-hd (1920×1080), desktop-2k, mobile (iPhone 15), mobile-landscape, android (Pixel 7), tablet (iPad), tablet-landscape. Also any Playwright device name ("iPhone 15 Pro Max", "Galaxy S24") or a size like "1366x768" / "390x844@3 mobile".

## `formats` (type: `array`):

One file per format from the same page load: png, jpeg, webp, pdf. Each delivered file is one billable capture.

## `fullPage` (type: `boolean`):

Capture the whole scrollable page (lazy images are scrolled into view first). Off = only the first screen (the viewport).

## `maxHeight` (type: `integer`):

Crop full-page captures to this many CSS pixels from the top, e.g. 3000 for "the top of the page". Empty = whole page (up to "Page height limit").

## `selector` (type: `string`):

Capture only this element (CSS selector, first match), e.g. "#pricing" or "main article". Pages where it never appears are reported as selector-not-found and not charged.

## `clip` (type: `object`):

Capture a fixed rectangle of the page in CSS pixels: {"x": 0, "y": 0, "width": 1200, "height": 630} (e.g. social cards).

## `quality` (type: `integer`):

1–100. Lower = smaller files.

## `deviceScaleFactor` (type: `integer`):

Override the device pixel ratio: 1 = standard, 2 = retina (4× the pixels). Leave empty to use each device's default.

## `viewportWidth` (type: `integer`):

Shortcut for one custom desktop viewport when "Devices" is empty (apify/screenshot-url compatible).

## `viewportHeight` (type: `integer`):

Height of the custom viewport (also the image height when Full page is off).

## `maxPageHeight` (type: `integer`):

Safety cap for endless pages: longer pages are cut here and flagged "truncated". WebP files are additionally limited to 16,383 px by the format.

## `waitUntil` (type: `string`):

When the page counts as loaded. "load" suits most sites; "networkidle" waits for background requests to settle (bounded by the idle timeout, never hangs).

## `waitForSelector` (type: `string`):

Wait until this CSS selector is visible before capturing (max 20 s, then captures anyway with a warning).

## `delay` (type: `integer`):

Wait this long after the page is ready (animations, charts). Max 60,000 ms.

## `scrollToBottom` (type: `boolean`):

Scroll down the page before capturing so lazy-loaded images and sections appear. On by default for full-page captures.

## `delayAfterScrolling` (type: `integer`):

Extra wait after the lazy-load scroll.

## `waitUntilNetworkIdleAfterScroll` (type: `boolean`):

After scrolling, wait (bounded by the idle timeout) until no requests are in flight.

## `networkIdleTimeoutMs` (type: `integer`):

Longest wait for network idle. The page is captured when it is reached.

## `pageTimeoutSecs` (type: `integer`):

Hard limit for one capture (load + waits + all files). A page that exceeds it is retried once, then reported as failed and not charged. The run never hangs on one page.

## `dismissCookieBanners` (type: `boolean`):

Click the visible "Accept" button of common consent banners (OneTrust, Cookiebot, Didomi, Quantcast, Sourcepoint, Usercentrics, ...) and hide leftovers. Never touches CAPTCHAs.

## `stickyElements` (type: `string`):

unstick = fixed headers appear once at the top, floating chat bubbles/bottom bars are removed; hide = remove all fixed/sticky elements; keep = leave as rendered.

## `hideSelectors` (type: `array`):

CSS selectors to hide before capturing (ads, popups, chat widgets).

## `selectorsToHide` (type: `string`):

apify/screenshot-url compatible: one CSS selector list, e.g. ".popup, #chat".

## `css` (type: `string`):

CSS injected before capture, e.g. "body { background: white }".

## `blockAds` (type: `boolean`):

Skip requests to major ad/analytics hosts: faster loads and cleaner captures.

## `blockResources` (type: `array`):

Do not load these request types. Default: media (video/audio — a screenshot cannot show it, and it costs CPU). Add font or image for speed; set to an empty list to load everything.

## `darkMode` (type: `boolean`):

Emulate prefers-color-scheme: dark (sites that support it render dark).

## `reducedMotion` (type: `boolean`):

Emulate prefers-reduced-motion (fewer animations; steadier captures for monitoring).

## `locale` (type: `string`):

Browser language, e.g. en-US, de-DE, ja-JP. Sites that localise by Accept-Language follow it.

## `timezoneId` (type: `string`):

IANA time zone, e.g. Europe/Berlin. Empty = UTC.

## `userAgent` (type: `string`):

Override the device's user agent string.

## `ignoreHttpsErrors` (type: `boolean`):

Capture pages with expired or self-signed certificates.

## `pdfFormat` (type: `string`):

Paper size for PDF output.

## `pdfLandscape` (type: `boolean`):

Landscape orientation.

## `pdfMedia` (type: `string`):

screen = the PDF looks like the page on screen; print = use the site's print stylesheet (cleaner articles).

## `pdfPrintBackground` (type: `boolean`):

Include background colours and images in the PDF.

## `pdfMarginPx` (type: `integer`):

Margin on every side.

## `onlyChanges` (type: `boolean`):

For scheduled runs: compare every capture with the last delivered one and deliver it only when it changed by at least the threshold, with the diff % and a highlighted diff image. Unchanged pages cost a cheaper monitor-check. The first run is the baseline.

## `monitorName` (type: `string`):

Separate baselines per schedule/task (e.g. "competitor-pricing").

## `changeThresholdPercent` (type: `string`):

Minimum share of the page (in %) that must differ to count as a change. Raise it for pages with rotating banners. Decimals allowed, e.g. "0.5".

## `changeTolerance` (type: `integer`):

0–255. How much a region's colour may shift before it counts as changed (ignores anti-aliasing noise).

## `includeUnchanged` (type: `boolean`):

Add a row with status "unchanged" (no files) for pages that did not change.

## `diffImage` (type: `boolean`):

For changed pages, also store a JPEG with the changed regions highlighted (included in the price).

## `includeBase64` (type: `boolean`):

Also put each file (up to 5 MB) into the dataset as base64 — handy for AI agents and no-code tools that cannot download URLs.

## `keyValueStoreName` (type: `string`):

Save files into this named key-value store (kept until you delete it, timestamped, never overwritten) instead of the run's default store.

## `respectRobotsTxt` (type: `boolean`):

Skip pages a site's robots.txt disallows (reported, not charged). Switch off only for sites you own or are allowed to capture.

## `maxRetries` (type: `integer`):

Retries for timeouts and network errors (with a fresh proxy session when a proxy is used).

## `maxConcurrency` (type: `integer`):

Pages rendered at once. 0 = automatic from the run memory (2 GB → 3).

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

Not needed for most sites (direct connection is fastest and included in the price). Use Apify datacenter proxy for other countries; RESIDENTIAL proxy is billed per MB of page traffic (residential-mb event).

## Actor input object example

```json
{
  "urls": [
    {
      "url": "https://apify.com"
    }
  ],
  "maxUrls": 1000,
  "devices": [
    "desktop"
  ],
  "formats": [
    "png"
  ],
  "fullPage": true,
  "quality": 80,
  "maxPageHeight": 20000,
  "waitUntil": "load",
  "delay": 0,
  "delayAfterScrolling": 0,
  "waitUntilNetworkIdleAfterScroll": false,
  "networkIdleTimeoutMs": 10000,
  "pageTimeoutSecs": 60,
  "dismissCookieBanners": true,
  "stickyElements": "unstick",
  "blockAds": true,
  "blockResources": [
    "media"
  ],
  "darkMode": false,
  "reducedMotion": false,
  "locale": "en-US",
  "ignoreHttpsErrors": false,
  "pdfFormat": "A4",
  "pdfLandscape": false,
  "pdfMedia": "screen",
  "pdfPrintBackground": true,
  "pdfMarginPx": 0,
  "onlyChanges": false,
  "monitorName": "default",
  "changeThresholdPercent": "1",
  "changeTolerance": 24,
  "includeUnchanged": false,
  "diffImage": true,
  "includeBase64": false,
  "respectRobotsTxt": true,
  "maxRetries": 1,
  "maxConcurrency": 0,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

One row per URL and device: file links, status, HTTP code, title, change info.

## `files` (type: `string`):

The stored screenshots and PDFs.

## `statistics` (type: `string`):

Per-run counters, failed pages with reasons, timings and traffic.

# 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": [
        {
            "url": "https://apify.com"
        }
    ],
    "devices": [
        "desktop"
    ],
    "formats": [
        "png"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("nat-labs/website-screenshot-scraper").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": [{ "url": "https://apify.com" }],
    "devices": ["desktop"],
    "formats": ["png"],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("nat-labs/website-screenshot-scraper").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": [
    {
      "url": "https://apify.com"
    }
  ],
  "devices": [
    "desktop"
  ],
  "formats": [
    "png"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call nat-labs/website-screenshot-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nat-labs/website-screenshot-scraper"
        }
    }
}
```

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/yqMg0drzF5050KFnj/builds/M6hNGU26IXTNfadL4/openapi.json
