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

Capture full-page screenshots (PNG, JPEG, WebP) and PDFs of any URL. Removes cookie banners, loads lazy images, fixes sticky headers, renders emoji and CJK text. Desktop, tablet, and mobile presets. You pay only for successful captures.

- **URL**: https://apify.com/catalyst-labs/website-screenshot-pdf-api.md
- **Developed by:** [Catalyst Labs](https://apify.com/catalyst-labs) (community)
- **Categories:** Developer tools, AI, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 screenshot captureds

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

### What is Website Screenshot & PDF API?

**Website Screenshot & PDF API** turns any public URL into a **full-page screenshot (PNG, JPEG or WebP)** or a **PDF**, with a direct link to every file. Give it one URL or a few thousand. It loads each page in a real Chrome browser, **clicks away cookie banners**, **loads lazy images**, **shows sticky headers once instead of on every screen**, **plays scroll-triggered animations to their final state**, hides chat widgets and popups, and then captures the page on desktop, tablet or mobile.

You **pay only for files that were actually captured**. Pages that fail, time out, are blocked by bot protection, return an HTTP error or render blank are reported with a reason and a fix hint, and they are **never charged**.

On Apify you also get **a REST API, MCP access for AI agents, scheduling, webhooks and integrations** (Make, Zapier, n8n, Google Drive and more) without running any servers or browsers yourself.

### How to use Website Screenshot & PDF API

1. Click **Try for free** (or **Start**) and open the **Input** tab.
2. Add your URLs, one per line. `https://` is optional.
3. Choose formats (PNG is the default; add `pdf`, `jpeg` or `webp`) and a device (`desktop`, `desktop-hd`, `laptop`, `tablet`, `mobile`).
4. Click **Start**. Each file appears in the **Output** tab with a preview and a `fileUrl` download link. The files are in the run's key-value store, and the `OUTPUT` record has a run summary.

***

### For AI agents

**What it does:** gives you an image or PDF of a web page so you can "see" it: one dataset record per URL and format, with `fileUrl` (a direct download link), `width`/`height`, `title` and `status`.

**Minimal input** (only `urls` is required):

```json
{ "urls": ["https://example.com"] }
```

**Cheap first call** (one above-the-fold JPEG, $0.018 on the Free plan: $0.01 run start + $0.008 screenshot):

```json
{ "urls": ["https://example.com"], "formats": ["jpeg"], "fullPage": false }
```

- **MCP tool name:** `catalyst-labs--website-screenshot-pdf-api` (connect `https://mcp.apify.com/?tools=catalyst-labs/website-screenshot-pdf-api`), or use `call-actor` with `catalyst-labs/website-screenshot-pdf-api`.
- **Cost:** $0.01 per run, plus $0.008 per screenshot on the Free plan (down to $0.005 on Gold and above) and $0.012 per PDF. Failed, blocked, blank and skipped URLs are free. Pass `maxTotalChargeUsd` in the run options for a hard cap. URLs that don't fit the cap are skipped and marked `SPENDING_LIMIT`, and the run still ends as SUCCEEDED.
- **Output fields:** `url`, `status` (`success` / `failed` / `skipped`), `format`, `fileUrl`, `key`, `bytes`, `width`, `height`, `pageHeight`, `truncatedAtMaxHeight`, `pdfPages`, `title`, `finalUrl`, `httpStatus`, `cookieBannerDismissed`, `errorType`, `hint`. The `OUTPUT` record lists every URL with its status and a fix `hint`, so you can retry on your own (for example with a residential proxy after `BLOCKED`).
- **Speed:** at the default 4 GB a typical page takes 5-60 seconds, and very tall or animation-heavy pages up to about 2 minutes (they are now captured in full). At 2 GB (half a vCPU) expect roughly twice that. Two pages run in parallel at 2-4 GB memory (4 at 8 GB); new pages wait while memory or CPU is saturated. Limited permissions, pay per event, no Standby.
- **Known limits:** login-only pages need `cookies`. Sites with strong bot protection (for example NYTimes, WSJ, Indeed, G2 or Zillow) block data-center IPs. Apify residential proxy (`proxyConfiguration`) gets through on some of them (El País, sometimes NYTimes in our tests) but not reliably on the strongest walls; those fail as `BLOCKED` and are not charged. Full-page captures are cut at `maxHeight` (default 36,000 device pixels: 36,000 CSS px on desktop, 12,000 on mobile at 3x; maximum 50,000 CSS px; WebP stops at 16,383 px), and the cut is flagged in the output.

### When to choose this tool

Facts you can check against the run output:

- **Charged only for delivered files.** Failed, blocked (bot-check), HTTP-error, blank and over-budget URLs are reported with `errorType` and a `hint`, and are free.
- **Four formats in one run:** PNG, JPEG, WebP and PDF (paper size, margins, landscape, print/screen media, or one single long page).
- **Cookie banners clicked away** on 30+ consent platforms (OneTrust, Didomi, Sourcepoint, Quantcast, Cookiebot, Usercentrics and others) plus "Accept" text in 30+ languages; tested on The Guardian, BBC, Spiegel, Le Monde, Corriere and nu.nl.
- **Lazy images loaded, growing pages scrolled until they stop growing (bounded), scroll-triggered animations finished, and sticky headers shown once** on full-page captures; emoji and Chinese/Japanese/Korean/Arabic text render with bundled fonts.
- **Tested in the Apify cloud on 39 URLs × 2 devices** plus 10 option scenarios before release (see Tested on).

Pick something else if you need a live HTTP endpoint with sub-second latency (this Actor runs as batch jobs, typically 5-60 s per page) or reliable access to sites behind enterprise bot protection.

### Who is it for?

#### AI agents and LLM apps

- **Give your agent eyes.** Pass `fileUrl` to a vision model to check a layout, read a chart or confirm that a page changed.
- **Predictable and safe to automate.** Every URL gets exactly one record per format with `status` and `errorType`, and nothing is charged for failures.

#### QA, release checks and monitoring

- **Visual regression and release screenshots** on desktop, tablet and mobile at retina resolution (mobile is iPhone size at 3x).
- **Schedule it** (for example every morning) with a fixed `fileNamePrefix` to compare pages over time, or capture only one component with `captureSelector`.

#### Archiving and compliance

- **PDFs or full-page images with the page title, final URL, HTTP status and capture time**, which works well as evidence of what a page showed and when. Use `pdfMediaType: "print"` for clean article PDFs, or `pdfSinglePage: true` for one long page with no page breaks.

#### Reporting pipelines and SEO

- **Competitor pages, landing pages and dashboards** captured in batches, linked straight from the dataset into Sheets, Slack or a report.

### Fixes for the most common screenshot-tool complaints

| Common complaint (Apify reviews/issues, screenshot API forums) | What this Actor does |
|---|---|
| "Cookie popup covers the content" | Clicks *Accept* on about 20 consent platforms (OneTrust, Didomi, Sourcepoint, Quantcast, Cookiebot, Usercentrics, TrustArc, Google Funding Choices, iubenda, CookieYes...) or on an accept button in 18 languages, then hides what's left. |
| "Sticky navbar repeated all over the full-page image" | `stickyElements: "static"` shows headers once at the top; `"hide"` removes them. |
| "Images/thumbnails missing" (lazy loading) | Scrolls the page in steps with short pauses, keeps going while the page grows (bounded by `maxScrollHeight`), promotes `data-src`/`loading=lazy` images, waits for them, then returns to the top. |
| "Animated sections are blank" (fade-in on scroll) | Lays the whole page out in one tall viewport so every scroll trigger fires, then jumps CSS/JS animations to their final frame (`freezeAnimations`, on by default). |
| "Bottom of long pages is blank" | Paints `content-visibility` sections, does not break body scrolling, and stitches tiles above Chrome's ~16k-pixel single-capture limit. |
| "Emoji show as boxes", CJK text missing | Ships Noto Color Emoji, Noto CJK and core fonts. |
| "Can't set the height / capture only the top" | `fullPage: false`, a custom `width`/`height`, `maxHeight` or `captureSelector` for one element. |
| "Loading forever / stuck run" | Bounded waits at every step, a hard per-URL timeout, and browser restart after a crash. One slow ad can't stall the run. |
| "It didn't work and still used my credits" | Only real captures are charged. Error pages, bot walls, blank renders and timeouts are free and come with a fix hint. |
| "Slow and expensive" | No per-run memory surprise: a flat price per file, ads/trackers blocked, and parallel pages sized to the run's memory. |

### Input example

```json
{
    "urls": ["https://apify.com", "https://www.theguardian.com/international"],
    "formats": ["png", "pdf"],
    "device": "mobile",
    "dismissCookieBanners": true,
    "stickyElements": "static",
    "maxHeight": 20000
}
```

All options are on the **Input** tab. They include `waitUntil`, `waitForSelector`, `delayMs`, `captureSelector`, `hideSelectors`, `customCss`, `darkMode`, `headers`, `cookies`, the PDF options (`pdfFormat`, `pdfLandscape`, `pdfMargin`, `pdfMediaType`, `pdfSinglePage`), `captureErrorPages`, `captureBlockedPages`, `retryBlockedWithProxy`, `freezeAnimations`, `maxScrollHeight`, timeouts, retries and proxy.

### Output example

```json
{
    "url": "https://www.theguardian.com/international",
    "status": "success",
    "format": "png",
    "fileUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/0000-www.theguardian.com-international.png?signature=...",
    "key": "0000-www.theguardian.com-international.png",
    "contentType": "image/png",
    "bytes": 17235046,
    "width": 1440,
    "height": 22664,
    "pageHeight": 22664,
    "truncatedAtMaxHeight": false,
    "device": "desktop",
    "title": "News, sport and opinion from the Guardian's global edition | The Guardian",
    "finalUrl": "https://www.theguardian.com/international",
    "httpStatus": 200,
    "cookieBannerDismissed": true,
    "cookieBannerMethod": "known:button.sp_choice_type_11",
    "errorType": null,
    "charged": true,
    "capturedAt": "2026-10-19T00:30:00.000Z"
}
```

A failed URL looks like `{"url": "https://www.nytimes.com/", "status": "failed", "errorType": "BLOCKED", "hint": "The site served a bot check. Retry with proxyConfiguration ...", "charged": false}`.

**Error types:** `INVALID_URL`, `BLOCKED`, `HTTP_ERROR`, `DNS_ERROR`, `CONNECTION_ERROR`, `TLS_ERROR`, `TIMEOUT`, `SELECTOR_NOT_FOUND`, `BLANK_PAGE`, `BROWSER_CRASH`, `REDIRECT_LOOP`, `NETWORK_ERROR`, `SPENDING_LIMIT`.

### How much does it cost to capture website screenshots?

Pay per event. You pay only for files that were delivered, with no separate charge for Apify platform usage. Prices drop with your Apify plan.

| Event | Free | Bronze | Silver | Gold and above |
| --- | --- | --- | --- | --- |
| Run started (once per run) | $0.01 | $0.01 | $0.01 | $0.01 |
| Screenshot (PNG, JPEG or WebP file) | $0.008 | $0.007 | $0.006 | $0.005 |
| PDF file | $0.012 | $0.012 | $0.012 | $0.012 |

**Cost examples (Free plan):**

- 1 screenshot: $0.018 ($0.01 run start + $0.008).
- 100 full-page screenshots in one run: $0.81.
- 1,000 screenshots in one run: $8.01 ($5.01 on Gold).
- 1,000 URLs as both PNG and PDF: $20.01.

Failed, blocked, blank and skipped URLs cost nothing. Each format you request is a separate file, and each file is charged once. To cap a run, set **Maximum cost per run** (`maxTotalChargeUsd`). The Actor stops cleanly before the cap and marks the remaining URLs `SPENDING_LIMIT`. Apify's $5 free monthly credit covers roughly 600 screenshots on the Free plan when you batch URLs into a few runs. Proxy traffic, including residential proxy if you turn it on, is included in these prices.

### Tested on

Cloud QA, October 18, 2026, build 1.0.12, default settings (4 GB, no proxy set):

- **Desktop:** 30 of 39 URLs captured, full length up to the 36,000 px default (React, Vercel, Linear, Figma, Notion, Airbnb, Amazon, Medium, Apple, Stripe, The Guardian, BBC, Le Monde, Spiegel, Corriere, El País, nu.nl, Zillow, Baidu, Yahoo Japan, Naver, Russian and English Wikipedia, Al Jazeera, Hacker News, GitHub, USA.gov, getemoji.com, Shopify, httpbin). Correctly refused and not charged: 6 bot walls (Unsplash, Zeit, NYTimes, WSJ, G2, FT; each retried once through Apify Proxy), Indeed (connection refused), a nonexistent domain and a 404 page.
- **Mobile (iPhone, 3x):** 27 of 39 captured. Medium, El País and Zillow also blocked on this run (bot walls vary by IP); none were charged.
- **Options:** all 4 formats in one run, PDF Letter/landscape/print, single-page PDF, element capture, wait-for-selector, dark mode, tablet viewport, custom size and 2x scale, custom headers and cookies, hidden selectors, custom CSS, file-name prefix, error-page capture and max-height cut-off behaved as expected; invalid URLs, a DNS error and an HTTP 500 failed with the right error type and were not charged; an expired TLS certificate and a 60 s slow response were captured.

### FAQ

**How long do the file links work?** `fileUrl` is a signed link to the run's key-value store, and anyone with the link can open it, with no token needed. Default run storage is kept for 7 days on the Apify Free plan and longer on paid plans. To keep files indefinitely, rename (name) the run's key-value store or copy the files to your own storage with an integration.

**Can it capture pages behind a login?** Yes, if you pass the session `cookies` (or an `Authorization` header). Only capture pages you are allowed to access.

**Why did a site fail with BLOCKED?** Some sites block cloud/data-center IPs. By default the Actor retries a blocked URL once through Apify Proxy (data-center) with a fresh browser context (`retryBlockedWithProxy`, on by default; skipped when you set your own proxy). If it is still blocked, retry with `"proxyConfiguration": {"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}`. This helps on some sites but not all: in our October 2026 tests, the strongest bot walls (WSJ, G2, Zillow, Indeed, FT) still blocked residential IPs. Blocked attempts are not charged by this Actor.

**Does it capture HTTPS sites with certificate errors?** Yes. Certificate errors are ignored, so expired or self-signed staging sites can still be captured.

**Very long pages?** Full pages up to 36,000 device pixels are captured by default (on desktop that fits a full English Wikipedia article of about 26,000 px or Spiegel's homepage of about 32,500 px). Raise `maxHeight` up to 50,000 CSS px, or lower it to cap file size; WebP is limited to 16,383 px. The per-URL timeout is extended automatically for very tall pages. Use JPEG for smaller files: the 22,664 px Guardian homepage was 17 MB as PNG and 2.8 MB as JPEG in our test.

**Is it legal?** Capturing publicly visible pages is generally fine, but you are responsible for how you use the images (copyright, personal data, terms of service). Don't use it to capture content you have no right to access.

**Something broke?** Open an issue on the **Issues** tab with the URL and the run ID. Fixes usually ship within a few days.

# Actor input Schema

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

Web pages to capture. Each URL gives one file per format. https:// is added if missing; duplicates are removed and invalid entries are reported for free. Example: \["https://apify.com", "example.com/pricing"]

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

Output formats per URL: "png", "jpeg", "webp" (screenshots) and/or "pdf". Each format is a separate file and charge. Default: \["png"]. Example: \["webp", "pdf"]

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

Capture the whole scrollable page (true) or only the first screen/viewport (false). Default: true. Example: false for a quick above-the-fold thumbnail.

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

Viewport preset: "desktop" (1440x900), "desktop-hd" (1920x1080), "laptop" (1280x800), "tablet" (820x1180 @2x) or "mobile" (iPhone 390x844 @3x, mobile user agent). Default: "desktop". Example: "mobile"

## `width` (type: `integer`):

Custom viewport width in CSS pixels; overrides the preset width. Example: 1366

## `height` (type: `integer`):

Custom viewport height in CSS pixels; overrides the preset. With fullPage false this is the image height. Example: 768

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

Pixel density (1-3). 2 or 3 gives retina-sharp images but larger files. Default: from the preset (desktop 1, mobile 3). Example: 2

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

Longest page part to capture, in CSS pixels. Leave empty for the default: the whole page up to 36,000 device pixels (36,000 px on desktop, 18,000 on tablet, 12,000 on mobile), which covers almost every real page, including very long news front pages and Wikipedia lists. Longer pages are cut here and flagged with truncatedAtMaxHeight: true. Max 50,000 (PNG/JPEG are also limited to 60,000 device pixels, WebP to 16,383). Example: 8000 for smaller, faster files.

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

JPEG/WebP quality, 1-100. Ignored for PNG and PDF. Default: 80. Example: 60 for smaller files.

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

When the page counts as loaded: "domcontentloaded" (fastest), "load" (default, waits up to 15 s for images) or "networkidle" (slowest, for heavy single-page apps). Example: "networkidle"

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

Wait until this CSS selector is visible before capturing (up to navigationTimeoutSecs). Use it for apps that render data late. Fails as SELECTOR_NOT_FOUND (not charged) if it never appears. Example: "#main-chart"

## `captureSelector` (type: `string`):

Capture only this element instead of the page (screenshots only). Fails as SELECTOR_NOT_FOUND (not charged) if missing. Example: "article", "#pricing-table"

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

Extra wait in milliseconds after loading and before capturing, for animations or late widgets. Max 60000. Default: 0. Example: 2000

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

Scroll through the page in steps (with short pauses) so lazy images, scroll-triggered sections and content loaded on scroll appear; keeps going while the page grows (bounded), then returns to the top. Default: true. Example: false for faster captures of short pages.

## `freezeAnimations` (type: `boolean`):

Put CSS animations, transitions and scroll-reveal effects (fade-ins, slide-ins, animated cards) in their final state, so the screenshot shows the finished page instead of half-faded or empty sections. Default: true. Example: false to capture the page exactly mid-animation.

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

Click "Accept" on cookie/consent banners (about 20 platforms such as OneTrust, Didomi, Sourcepoint, Cookiebot and Usercentrics, plus accept buttons in 18 languages) and hide what is left. Default: true. Example: false to capture the banner itself.

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

Hide newsletter popups, full-screen overlays and chat widgets (Intercom, Drift, HubSpot, Zendesk and others). Default: true.

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

How to handle sticky/fixed headers in full-page captures: "static" (show once at the top, default), "hide" (remove them) or "keep" (leave as the browser draws them; may repeat). Example: "hide"

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

CSS selectors of elements to hide before capturing. Example: \[".ad-slot", "#promo-bar"]

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

CSS injected before capturing. Example: "body { font-size: 18px } .banner { display: none }"

## `headers` (type: `object`):

Extra HTTP headers sent with every request (Host, Content-Length and similar are ignored). Example: {"Accept-Language": "de-DE", "Authorization": "Bearer abc"}

## `cookies` (type: `array`):

Cookies set before loading, for logged-in or region-specific pages. Each needs name and value; domain defaults to the URL host. Example: \[{"name": "session", "value": "abc123", "domain": ".example.com"}]

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

Emulate the dark color scheme (prefers-color-scheme: dark). Only changes sites that support dark mode. Default: false.

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

Block common ad and tracking hosts. Faster, cleaner captures. Default: true.

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

PDF paper size: "A4" (default), "Letter", "Legal", "A3" or "Tabloid". Example: "Letter"

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

Landscape PDF pages. Default: false.

## `pdfMargin` (type: `string`):

PDF page margin on all sides, in CSS units. Default: "10mm". Example: "0" or "0.5in"

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

Include background colors and images in PDFs. Default: true.

## `pdfMediaType` (type: `string`):

CSS media for PDFs: "screen" (looks like the website, default) or "print" (uses the site's print stylesheet, often cleaner for articles). Example: "print"

## `pdfSinglePage` (type: `boolean`):

Make the PDF one long page with the full page height and no page breaks, like a full-page screenshot in vector form. Default: false.

## `captureErrorPages` (type: `boolean`):

Capture and charge pages that return HTTP 4xx/5xx (for example to document a 404). Default: false, so error pages fail as HTTP_ERROR and are not charged.

## `captureBlockedPages` (type: `boolean`):

Capture and charge bot-check/challenge pages (Cloudflare, DataDome...) instead of failing as BLOCKED. Default: false, so blocked pages are not charged.

## `retryBlockedWithProxy` (type: `boolean`):

When a site answers with a bot check and you did not set your own proxy, retry that URL once through Apify Proxy (datacenter) with a fresh, regular browser. Blocked pages are never charged, whether or not the retry works. Default: true. Example: false to fail fast on blocked sites.

## `navigationTimeoutSecs` (type: `integer`):

Seconds to wait for the page to start loading and for waitForSelector. Default: 45. Example: 90 for slow sites.

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

Time limit in seconds for one URL (load, scroll and capture). Leave empty for 120 s, or up to 240 s automatically on runs with less than 4 GB memory (less than 1 vCPU). Very tall pages automatically get extra time (up to +120 s) once their height is known.

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

Retries for temporary errors (timeouts, network, crashes, blank pages). DNS, HTTP and selector errors are not retried. Default: 1. Example: 2

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

How many pages to load in parallel. Leave empty for automatic: 1 below 2 GB memory, 2 at 2–4 GB, then 1 per 2 GB (4 at 8 GB, max 8). New pages also wait while memory is above 70% or CPU is saturated, and only one very tall page per vCPU is laid out at a time.

## `perHostConcurrency` (type: `integer`):

Max parallel pages on the same website, to stay polite and avoid rate limits. Default: 2.

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

Proxy for all requests. Not needed for most sites; for sites that block data centers use Apify residential proxy. Example: {"useApifyProxy": true, "apifyProxyGroups": \["RESIDENTIAL"]}

## `fileNamePrefix` (type: `string`):

Prefix for file keys in the key-value store. Example: "release-42" gives keys like "release-42-0000-example.com.png"

## Actor input object example

```json
{
  "urls": [
    "https://apify.com",
    "https://en.wikipedia.org/wiki/Web_scraping"
  ],
  "formats": [
    "png"
  ],
  "fullPage": true,
  "device": "desktop",
  "quality": 80,
  "waitUntil": "load",
  "delayMs": 0,
  "scrollToBottom": true,
  "freezeAnimations": true,
  "dismissCookieBanners": true,
  "hidePopups": true,
  "stickyElements": "static",
  "headers": {},
  "cookies": [],
  "darkMode": false,
  "blockAds": true,
  "pdfFormat": "A4",
  "pdfLandscape": false,
  "pdfMargin": "10mm",
  "pdfPrintBackground": true,
  "pdfMediaType": "screen",
  "pdfSinglePage": false,
  "captureErrorPages": false,
  "captureBlockedPages": false,
  "retryBlockedWithProxy": true,
  "navigationTimeoutSecs": 45,
  "maxRetries": 1,
  "perHostConcurrency": 2,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `captures` (type: `string`):

Success and failure records: fileUrl, status, format, width/height, pdfPages, errorType.

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

All PNG/JPEG/WebP/PDF files from this run.

## `summary` (type: `string`):

Counts of succeeded, failed and skipped URLs, error types and charged events.

# 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": [
        "https://apify.com",
        "https://en.wikipedia.org/wiki/Web_scraping"
    ],
    "headers": {},
    "cookies": [],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("catalyst-labs/website-screenshot-pdf-api").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": [
        "https://apify.com",
        "https://en.wikipedia.org/wiki/Web_scraping",
    ],
    "headers": {},
    "cookies": [],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("catalyst-labs/website-screenshot-pdf-api").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": [
    "https://apify.com",
    "https://en.wikipedia.org/wiki/Web_scraping"
  ],
  "headers": {},
  "cookies": [],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call catalyst-labs/website-screenshot-pdf-api --silent --output-dataset

```

## MCP server setup

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

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/Q0IjIMqCA5OnecDNj/builds/Hpo08hBzBqOn4bppq/openapi.json
