# Website Screenshot & PDF (Full Page, Any Device) (`pagecraft/website-screenshot-pdf`) Actor

Clean full-page screenshots and PDFs of any website, with cookie banners, consent pop-ups and chat widgets removed automatically. Desktop, laptop, tablet and phone in one run. JPEG, PNG, WebP or PDF. Failed and blocked pages are never charged. Works with AI agents via MCP.

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

## Pricing

from $3.00 / 1,000 screenshots

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, Any Device)

Capture **clean, full-page screenshots and PDFs of any website** in seconds. Paste in your URLs, pick your devices and get pixel-perfect images back, with **cookie banners, consent pop-ups and chat widgets removed automatically**.

Ideal for website monitoring, design reviews, client reports, archiving, competitor tracking, social previews, QA and feeding visual context to AI agents.

### Why this screenshot tool?

- 🍪 **No cookie banners.** Accepts or hides consent dialogs from OneTrust, Cookiebot, Didomi, Quantcast, Usercentrics, Google, Sourcepoint and many more, including ones inside iframes and Shadow DOM. Works in English, German, French, Spanish, Italian, Dutch and more.
- 📱 **Every device in one run.** Desktop, laptop, MacBook Retina, widescreen, iPad, iPhone 15 Pro, Pixel 7 or any custom size. Pick several and get a full responsive check per URL.
- 📜 **True full-page captures.** Scrolls the page first so lazy-loaded images and sections actually appear.
- 🧹 **Clean output.** Chat bubbles (Intercom, Drift, HubSpot, Zendesk, Crisp, Tawk) hidden, ads, trackers and autoplay video blocked, scrollbars and caret removed, animations frozen.
- 🖼️ **JPEG, PNG, WebP or PDF.** Optimised compression, optional resizing for thumbnails, 1×, 2× or 3× pixel density.
- 🌙 **Dark mode**, custom CSS, wait-for-element, custom delays, browser language and time zone.
- 💸 **Fair pricing.** Quick failures are retried automatically; a page that still fails or blocks us costs a small fee, far below a capture.
- 🤖 **AI-agent ready.** Works through the Apify API and the Apify MCP server, so Claude, ChatGPT, Cursor and other agents can take screenshots for you.

### How to use it

1. Add one or more URLs (example.com works without https://).
2. Choose devices and an output format.
3. Click **Start**. Each screenshot appears in the results table with a preview and a direct download link.

### Input example

```json
{
  "urls": [{ "url": "https://apify.com" }, { "url": "https://www.bbc.co.uk" }],
  "devices": ["desktop", "iphone"],
  "format": "jpeg",
  "captureMode": "fullPage",
  "removeCookieBanners": true
}
```

### Output example

Each capture produces one dataset item. The image itself is stored in the run's key-value store, and `screenshotUrl` links straight to it.

```json
{
  "url": "https://apify.com",
  "finalUrl": "https://apify.com/",
  "title": "Apify: Full-stack web scraping and data extraction platform",
  "statusCode": 200,
  "device": "iphone",
  "deviceLabel": "iPhone 15 Pro",
  "format": "jpeg",
  "captureMode": "fullPage",
  "screenshotUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/0001-apify-com-iphone.jpg",
  "width": 1179,
  "height": 15999,
  "fileSizeBytes": 412530,
  "cookieBannerDismissed": true,
  "loadTimeMs": 6120,
  "capturedAt": "2026-10-27T10:00:00.000Z",
  "error": null
}
```

Download results as JSON, CSV, Excel or HTML, or fetch them with the API.

### Options at a glance

| Option | What it does |
| --- | --- |
| Devices | Desktop, laptop, MacBook Retina, widescreen, iPad, iPhone, Android, custom |
| What to capture | Full page, visible area only, or a single element by CSS selector |
| Output format | JPEG (default, fastest), PNG (lossless), WebP (smallest), PDF |
| Remove cookie banners | On by default |
| Hide chat widgets and popups | On by default |
| Block ads, trackers and video | On by default |
| Dark mode | Renders the site's dark theme if it has one |
| Resize output | Shrink to a set width for thumbnails |
| Pixel density | 1×, 2× or 3× |
| PDF options | Paper size, landscape, backgrounds, screen or print styles |
| Timing | Wait until loaded or network idle, extra delay, wait for an element |
| Advanced | Extra elements to hide, custom CSS, language, time zone, proxy, retries |

### Pricing

Pay per capture, with no platform usage charges on top. You pay less for short captures, because they are much cheaper to make:

| Capture | Free plan | Bronze | Silver | Gold |
| --- | --- | --- | --- | --- |
| **Screenshot** (visible area, an element, or a page up to 3 screens tall, captured in under 30 seconds with under 3 MB downloaded) | $5 / 1,000 | $4 / 1,000 | $3.50 / 1,000 | $3 / 1,000 |
| **Full-page screenshot** (taller pages), **PDF**, or a **heavy page** that takes over 30 seconds or downloads more than 3 MB to capture | $12 / 1,000 | $10 / 1,000 | $9 / 1,000 | $8 / 1,000 |

- **Per run:** a tiny start fee of $0.001 per GB of memory ($0.002 at the default 2 GB).
- **Failed or blocked pages** cost $3 / 1,000 per started 20 seconds of work (most failures take one unit), because they still use a browser. Each result shows how it was billed in `billedAs`, and how long it took in `loadTimeMs`.
- **Limits:** each page has an overall limit of 75 seconds, and after 6 MB of downloads its remaining images, scripts and fonts are skipped. Each result shows `downloadedMb`. If most pages in a run fail, the run stops early so you don't wait on a bad list.

Set **Maximum cost per run** to cap your spend: the tool only processes as many pages as your limit covers. Batch many URLs into one run for the best value.

### Use with AI agents (MCP)

Add this Actor to your agent through the [Apify MCP server](https://mcp.apify.com/) and ask things like "screenshot the pricing pages of these three competitors on desktop and mobile". The agent gets back image links it can show or analyse.

### Use the API

```bash
curl -X POST "https://api.apify.com/v2/acts/pagecraft~website-screenshot-pdf/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"urls":[{"url":"https://example.com"}],"format":"jpeg"}'
```

### Tips

- Very long pages are cut off at 15,000 px by default (adjustable). High pixel densities are capped at 16,000 output pixels tall so files stay usable.
- For single-page apps that load slowly, choose **Network idle** or add **Wait for element**.
- If a site blocks automated browsers, try the datacenter proxy option. Pages that answer with a block (HTTP 401, 403, 429 or 503) are returned with an error and the small failed-capture fee.
- Need it faster? Give the run more memory: the tool captures one page in parallel per GB.

### Responsible use

Only capture pages you're allowed to access. Private and local network addresses are blocked. This tool doesn't log in to websites or collect personal data from pages.

### Feedback

Found a page that doesn't capture cleanly? Open an issue on the Issues tab with the URL and it will be looked at quickly.

# Actor input Schema

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

Web pages to capture. Add as many as you like. Domains without https:// are fine (e.g. example.com).

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

Capture each URL on one or more devices. Choose several for a full responsive check in one run. Each URL × device is one capture.

## `format` (type: `string`):

JPEG is fastest and small. PNG is lossless but larger. WebP gives the smallest files. PDF creates a multi-page document of the page.

## `captureMode` (type: `string`):

Full page scrolls the whole page. Viewport captures only what is visible on screen. Element captures a single part of the page (set a CSS selector). Ignored for PDF.

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

Only for 'A specific element' mode, e.g. #pricing or .hero.

## `removeCookieBanners` (type: `boolean`):

Accepts or hides cookie and consent dialogs (OneTrust, Cookiebot, Didomi, Quantcast, Usercentrics and many more) so they don't cover the page.

## `hidePopups` (type: `boolean`):

Hides live-chat bubbles (Intercom, Drift, HubSpot, Zendesk, Crisp, Tawk) and leftover consent overlays.

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

Blocks common ad, analytics and tracking networks and video streams. Pages load faster and look cleaner.

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

Ask the page to render its dark theme, if it has one.

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

1 to 100. Higher is sharper but larger.

## `outputWidth` (type: `integer`):

Shrink the final image to this width, keeping proportions. Great for thumbnails. 0 keeps the original size.

## `scaleFactor` (type: `string`):

Override the device pixel ratio. 2 gives Retina-sharp images. 0 uses each device's default.

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

Very long pages are cut off at this height to keep files usable.

## `customWidth` (type: `integer`):

Used when the 'Custom size' device is selected.

## `customHeight` (type: `integer`):

Used when the 'Custom size' device is selected.

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

Paper size for PDF output.

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

Use landscape orientation.

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

Keep background colours and images in the PDF.

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

'Screen' makes the PDF look like the website. 'Print' uses the site's print stylesheet, if any.

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

When the page counts as loaded. 'Page loaded' waits up to 10 seconds for the load event, then captures anyway, so slow trackers never stall your run. 'Network idle' is slowest but safest for heavy JavaScript apps.

## `delayMs` (type: `integer`):

Wait this long after loading, for animations or late content.

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

Optional CSS selector to wait for before capturing, e.g. .chart-loaded.

## `scrollToLoad` (type: `boolean`):

Scrolls through the page first so lazy-loaded images and sections appear in full-page captures.

## `timeoutSecs` (type: `integer`):

Give up on loading a page after this long (10 to 30 seconds). Every page also has an overall limit of 75 seconds.

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

CSS selectors to hide before capture, e.g. .banner, #promo.

## `customCss` (type: `string`):

CSS injected into every page before capture.

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

Language/locale the browser reports, e.g. en-GB, de-DE, fr-FR.

## `timezone` (type: `string`):

IANA time zone, e.g. Europe/London. Leave empty for UTC.

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

Retry a page that fails quickly (up to this many times). Slow failures are not retried. A failed or blocked capture has a small fee (see Pricing).

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

Optional. Use Apify datacenter proxies or your own proxy URLs for sites that block automated browsers. Residential proxies are not supported.

## Actor input object example

```json
{
  "urls": [
    {
      "url": "https://apify.com"
    },
    {
      "url": "https://www.bbc.co.uk"
    }
  ],
  "devices": [
    "desktop"
  ],
  "format": "jpeg",
  "captureMode": "fullPage",
  "removeCookieBanners": true,
  "hidePopups": true,
  "blockAds": true,
  "darkMode": false,
  "quality": 80,
  "outputWidth": 0,
  "scaleFactor": "0",
  "maxHeight": 15000,
  "customWidth": 1280,
  "customHeight": 800,
  "pdfFormat": "A4",
  "pdfLandscape": false,
  "pdfPrintBackground": true,
  "pdfMedia": "screen",
  "waitUntil": "load",
  "delayMs": 1000,
  "scrollToLoad": true,
  "timeoutSecs": 30,
  "locale": "en-US",
  "maxRetries": 2
}
```

# Actor output Schema

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

No description

## `files` (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": [
        {
            "url": "https://apify.com"
        },
        {
            "url": "https://www.bbc.co.uk"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("pagecraft/website-screenshot-pdf").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" },
        { "url": "https://www.bbc.co.uk" },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("pagecraft/website-screenshot-pdf").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"
    },
    {
      "url": "https://www.bbc.co.uk"
    }
  ]
}' |
apify call pagecraft/website-screenshot-pdf --silent --output-dataset

```

## MCP server setup

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

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/784ENbiBN9K5MDsl1/builds/Vf63Ym4i6FIMQoSq6/openapi.json
