# Website Screenshot & PDF API (`datadock-labs/website-screenshot-pdf`) Actor

Capture full-page screenshots (PNG, JPEG) and PDFs of any website. Hides cookie banners, blocks ads, emulates phones, tablets and dark mode. Run in batch or call it as a real-time HTTP API.

- **URL**: https://apify.com/datadock-labs/website-screenshot-pdf.md
- **Developed by:** [DataDock Labs](https://apify.com/datadock-labs) (community)
- **Categories:** Developer tools, Automation, AI
- **Features:** Limited permissions, Single-tenant, Server interface
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 screenshot captureds

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

## Website Screenshot & PDF API

Capture **full-page screenshots** (PNG or JPEG) and **PDFs** of any public web page, in bulk or in real time. Cookie banners and ads are removed automatically, so screenshots look the way a visitor sees the page, without the clutter.

- 📸 **Full-page, viewport or single-element** screenshots in PNG or JPEG
- 📄 **URL to PDF** with paper size, orientation, margins and print/screen styles
- 🍪 **Hides cookie-consent banners** of the most common consent platforms (OneTrust, Cookiebot, Quantcast, Didomi, Usercentrics and 20+ more)
- 🚫 **Blocks ads and trackers** and collapses empty ad slots, so pages load faster
- 📱 **Phone and tablet emulation** (iPhone, Pixel, Galaxy, iPad), **retina** output and **dark mode**
- 🖱️ **Lazy-loaded images** appear: the page is scrolled before full-page captures
- ⚡ **Real-time HTTP API** (Standby mode): send a URL, get the image back in about a second
- 💸 **Pay only for successful captures.** Failed pages cost nothing.

![A plain screenshot blocked by a cookie consent wall, next to the same page captured by this Actor with the banner and ads removed](https://api.apify.com/v2/key-value-stores/j4HuWJS9p2N3Tu0Jd/records/screenshot-before-after.jpg)

### What can I use it for?

- Website monitoring and visual change tracking
- Archiving pages, receipts and articles as PDF
- Social media previews, thumbnails and link cards
- SEO and competitor audits (desktop and mobile)
- Feeding page images to AI agents and vision models
- QA: checking how a site looks on different devices or in dark mode

### How to use it

#### In Apify Console (no code)

1. Paste one or more URLs into **URLs** (or upload a text file with one URL per line).
2. Pick **PNG**, **JPEG** or **PDF**. Defaults work for most pages.
3. Click **Start**. Files appear in the **Output** tab with a preview, and stay in the run's key-value store.

#### Via the API (batch)

```bash
curl -X POST "https://api.apify.com/v2/acts/datadock-labs~website-screenshot-pdf/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json" \
  -d '{"urls":[{"url":"https://apify.com"},{"url":"https://example.com"}],"format":"png"}'
```

Each dataset item contains a `fileUrl` you can download.

#### As a real-time API (Standby mode)

The Actor also runs as an always-ready web server. Send a GET or POST request and the response **is the image or PDF itself**. You can find the server URL in the **Server** tab of this Actor.

```bash
## PNG screenshot of the full page
curl -H "Authorization: Bearer $APIFY_TOKEN" \
  "https://datadock-labs--website-screenshot-pdf.apify.actor/?url=https://apify.com" -o page.png

## Mobile screenshot of the visible area, as JPEG
curl -H "Authorization: Bearer $APIFY_TOKEN" \
  "https://datadock-labs--website-screenshot-pdf.apify.actor/?url=https://apify.com&device=iphone-15-pro&full_page=false&format=jpeg" -o mobile.jpg

## PDF on Letter paper
curl -H "Authorization: Bearer $APIFY_TOKEN" \
  "https://datadock-labs--website-screenshot-pdf.apify.actor/pdf?url=https://apify.com&paper=Letter" -o page.pdf
```

```javascript
// Node.js 18+
const res = await fetch('https://datadock-labs--website-screenshot-pdf.apify.actor/', {
    method: 'POST',
    headers: { Authorization: `Bearer ${process.env.APIFY_TOKEN}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ url: 'https://apify.com', format: 'png', darkMode: true }),
});
const image = Buffer.from(await res.arrayBuffer());
```

```python
import os, requests
r = requests.get(
    "https://datadock-labs--website-screenshot-pdf.apify.actor/",
    params={"url": "https://apify.com", "format": "pdf"},
    headers={"Authorization": f"Bearer {os.environ['APIFY_TOKEN']}"},
)
open("page.pdf", "wb").write(r.content)
```

**Endpoints:** `/` and `/screenshot` (format from the `format` parameter), `/pdf` (always PDF).
**Response:** the file (`image/png`, `image/jpeg` or `application/pdf`). Add `response=json` to get metadata plus the file as base64.
**Headers:** `X-Final-Url`, `X-Http-Status`, `X-Load-Time-Ms`, `X-Warnings`.
**Errors:** `400` invalid input or URL, `422` the page could not be captured (not charged), `402` your run's spending limit was reached.

### Input

All fields except `urls` are optional. In Standby mode use the same names as query parameters or JSON fields; short aliases are accepted (`width`, `height`, `full_page`, `quality`, `delay`, `timeout`, `dark`, `hide`, `css`, `js`, `paper`, `landscape`, `margin`).

| Field | Default | Description |
|---|---|---|
| `urls` | – | Pages to capture (batch mode). Standby mode uses `url`. |
| `format` | `png` | `png`, `jpeg` or `pdf` |
| `fullPage` | `true` | Whole page or only the visible viewport |
| `device` | `desktop` | `desktop`, `iphone-15-pro`, `iphone-se`, `pixel-7`, `galaxy-s9`, `ipad-pro-11`, `ipad-mini` |
| `viewportWidth` / `viewportHeight` | `1366` / `768` | Desktop window size in px |
| `scaleFactor` | `1` | `2` or `3` for retina images (desktop) |
| `hideCookieBanners` | `true` | Hide cookie-consent pop-ups |
| `blockAds` | `true` | Block ads/trackers and collapse ad slots |
| `darkMode` | `false` | Prefer the site's dark theme |
| `hideSelectors` | – | CSS selectors to hide |
| `customCss` / `customJs` | – | CSS or JavaScript applied before the capture |
| `waitUntil` | `load` | `load`, `domcontentloaded`, `networkidle`, `commit` |
| `waitForSelector` | – | Wait until this element is visible |
| `delayMs` | `0` | Extra wait in milliseconds |
| `selector` | – | Capture only this element |
| `jpegQuality` | `80` | JPEG quality 1-100 |
| `omitBackground` | `false` | Transparent background (PNG) |
| `maxHeight` | `16000` | Long pages are cut at this height (px) |
| `pdfFormat`, `pdfLandscape`, `pdfMarginMm`, `pdfPrintBackground`, `pdfMedia` | `A4`, `false`, `10`, `true`, `print` | PDF layout |
| `skipHttpErrors` | `false` | Skip (and don't charge for) pages that return HTTP 400+ |
| `timeoutSecs` | `30` | Page load timeout; slow pages are still captured with what rendered |
| `maxConcurrency` | `3` | Pages captured in parallel (batch mode) |
| `proxyConfiguration` | off | Optional Apify Proxy, for example to see a page from another country |

```json
{
    "urls": [{ "url": "https://apify.com" }],
    "format": "png",
    "fullPage": true,
    "device": "desktop",
    "hideCookieBanners": true,
    "blockAds": true
}
```

### Output

Each page produces one dataset item. Files are stored in the run's default key-value store.

```json
{
    "url": "https://apify.com",
    "status": "succeeded",
    "format": "png",
    "device": "desktop",
    "fullPage": true,
    "fileUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/0001-apify-com.png",
    "screenshotUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/0001-apify-com.png",
    "fileKey": "0001-apify-com.png",
    "finalUrl": "https://apify.com/",
    "httpStatus": 200,
    "title": "Apify: Full-stack web scraping and data extraction platform",
    "width": 1366,
    "height": 7421,
    "pdfPages": null,
    "bytes": 2481930,
    "loadTimeMs": 2875,
    "warnings": [],
    "error": null,
    "capturedAt": "2026-11-08T12:00:00.000Z"
}
```

Failed pages have `"status": "failed"` and an `error` message, for example `Domain not found: exmaple.com`.

### Pricing

This Actor uses **pay-per-event** pricing. You pay for each successful capture, with discounts on higher Apify plans:

| Event | Free & Bronze plans | Silver | Gold and above |
|---|---|---|---|
| Screenshot (PNG or JPEG) | **$4.00** / 1,000 | $3.50 / 1,000 | $3.00 / 1,000 |
| PDF | **$4.00** / 1,000 | $3.50 / 1,000 | $3.00 / 1,000 |

Failed pages, invalid URLs and skipped error pages are free. In batch mode the price above is all you pay. In Standby (real-time API) mode Apify also bills the server's platform usage to your account.

You can set a maximum cost per run in Apify Console; the Actor stops cleanly when the limit is reached.

### Use with AI agents

AI agents can call this Actor through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) to "see" a web page, then pass the screenshot to a vision model. The `screenshotUrl` field links straight to the image.

### Integrations

Use the Actor from Make, Zapier, n8n, Google Sheets, Slack, webhooks or the Apify API clients for JavaScript and Python. For example, schedule a daily run to screenshot your landing pages and get the files in Slack.

### FAQ

**Can it capture pages behind a login?** No. It is built for public pages and does not handle accounts or passwords.

**Are cookie banners accepted?** No. Banners are only hidden with CSS. Nothing is clicked, so no consent is given on your behalf.

**Why is a very long page cut off?** Pages taller than `maxHeight` (16,000 px by default) are cut to keep files usable and captures fast. Lower it for smaller files.

**Why does a page look different from my browser?** Some sites show different content to new visitors, other regions or headless browsers. Try a proxy from your country, a longer `delayMs`, or `waitUntil: networkidle`.

**Which websites can't be captured?** Local and private network addresses are blocked for security, and some sites block automated browsers. Such pages fail and are not charged.

**Is there a free website screenshot API?** Every Apify account includes free monthly credits, so you can try this Actor without paying. After that you pay only for successful captures ($4 per 1,000, less on Silver and Gold plans).

**How do I take a full-page screenshot of a website with an API?** Call the Standby endpoint with `?url=...` (full page is the default) or run the Actor with a list of URLs. Lazy-loaded images are scrolled into view first.

**How do I convert a web page to PDF?** Use the `/pdf?url=...` endpoint or set `format` to `pdf`. Pick paper size, orientation and margins; `pdfMedia: screen` keeps the on-screen design.

**Can I capture thousands of URLs at once?** Yes. Paste or upload a list of URLs; pages are captured in parallel and every file gets its own link in the dataset.

**Is it legal?** Taking screenshots of public web pages is generally fine, but the content belongs to its owners. Respect copyright and the sites' terms when you reuse the images.

### Changelog

- **0.1** (November 2026): first release. PNG/JPEG/PDF, cookie banner and ad removal, device emulation, dark mode, lazy loading, Standby HTTP API.

### More from DataDock Labs

- [Google Sheets Sync: Export & Import](https://apify.com/datadock-labs/google-sheets-sync): add it as an integration of this Actor to log every capture (URL, title, file link, size) in a Google Sheet automatically.

### Support

Found a page that doesn't look right? Open an issue on the **Issues** tab with the URL and your input. You can also email <datadocklabs@gmail.com> or see the [support page](https://datadock-labs.github.io/support.html). More tools from DataDock Labs: [datadock-labs.github.io](https://datadock-labs.github.io/).

If this Actor saves you time, a short review on its Store page helps other people find it. Thank you!

# Actor input Schema

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

Web pages to capture. You can paste URLs, upload a text file or link a remote list.

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

PNG is lossless, JPEG is smaller, PDF produces a printable document.

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

Capture the whole scrollable page instead of only the visible viewport.

## `device` (type: `string`):

Emulate a phone or tablet (viewport, pixel density, user agent and touch). Desktop uses the viewport size below.

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

Browser window width for the desktop device.

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

Browser window height for the desktop device. With full-page off, this is the screenshot height.

## `scaleFactor` (type: `integer`):

1 = normal, 2 = retina (twice the pixels), 3 = extra sharp. Desktop device only.

## `hideCookieBanners` (type: `boolean`):

Hide cookie-consent and GDPR pop-ups of the most common consent platforms (nothing is clicked or accepted).

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

Block requests to common ad, analytics and session-recording services. Pages load faster and look cleaner.

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

Tell the website the visitor prefers a dark color scheme (works on sites that support it).

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

CSS selectors of elements to hide, for example chat widgets or sticky headers.

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

CSS injected into the page before the capture.

## `customJs` (type: `string`):

JavaScript run in the page before the capture (for example to click a tab). Async code and await are supported; it is stopped after 15 seconds.

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

When navigation counts as finished. 'load' fits most pages; 'networkidle' waits for late requests too.

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

CSS selector that must be visible before the capture.

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

Additional wait after the page is ready, for animations or late content.

## `lazyLoad` (type: `boolean`):

Scroll through the page before full-page and PDF captures so lazy-loaded images appear.

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

Maximum time to load one page. Slow pages are still captured with whatever was rendered.

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

CSS selector of a single element to capture (for example a chart or a product card). Images only.

## `jpegQuality` (type: `integer`):

1-100. Lower values give smaller files.

## `omitBackground` (type: `boolean`):

Make the default white page background transparent.

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

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

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

Paper size of the PDF.

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

Landscape page orientation.

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

Include background colors and images.

## `pdfMarginMm` (type: `integer`):

Page margin on all sides.

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

'print' uses the site's print stylesheet, 'screen' makes the PDF look like the website on screen.

## `skipHttpErrors` (type: `boolean`):

Do not capture (and do not charge for) pages that answer with HTTP 400 or higher.

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

Override the browser user agent string.

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

How many times to retry a page that fails to load.

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

How many pages are captured at the same time. Increase memory when you raise this.

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

Optional proxy, for example to see a page from another country.

## Actor input object example

```json
{
  "urls": [
    {
      "url": "https://apify.com"
    }
  ],
  "format": "png",
  "fullPage": true,
  "device": "desktop",
  "viewportWidth": 1366,
  "viewportHeight": 768,
  "scaleFactor": 1,
  "hideCookieBanners": true,
  "blockAds": true,
  "darkMode": false,
  "waitUntil": "load",
  "delayMs": 0,
  "lazyLoad": true,
  "timeoutSecs": 30,
  "jpegQuality": 80,
  "omitBackground": false,
  "maxHeight": 16000,
  "pdfFormat": "A4",
  "pdfLandscape": false,
  "pdfPrintBackground": true,
  "pdfMarginMm": 10,
  "pdfMedia": "print",
  "skipHttpErrors": false,
  "maxRetries": 1,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# 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"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("datadock-labs/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" }],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("datadock-labs/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"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call datadock-labs/website-screenshot-pdf --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datadock-labs/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/06CDwVC0HXlbK5OHf/builds/Ucodywhw1B7ebL9US/openapi.json
