# Website Screenshot & PDF - Reliable Capture (`amazing_wizdom/web-screenshot-capture`) Actor

Capture full-page or viewport screenshots (PNG/JPEG) and PDFs of any URL. Waits for the page to settle, dismisses cookie banners, supports device presets and custom waits. Pay only for successful captures.

- **URL**: https://apify.com/amazing\_wizdom/web-screenshot-capture.md
- **Developed by:** [Constantine](https://apify.com/amazing_wizdom) (community)
- **Categories:** Developer tools, Automation, AI
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

$20.00 / 1,000 screenshot / pdf captureds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Website Screenshot & PDF - Reliable Capture

**Capture full-page or viewport screenshots (PNG/JPEG) and PDFs of any URL — with the waiting and cookie-banner handling that make captures actually look right.**

A lot of screenshot tools fire too early and hand you a half-loaded page, a spinner, or a giant cookie banner covering the content. This actor waits for the page to settle, dismisses common consent banners, and lets you wait for a specific element before it captures. You pay only for captures that succeed.

***

### Why this actor

| | This actor | Bare screenshot tools |
|---|---|---|
| **Page readiness** | Waits for `networkidle` (or your rule) + optional selector | Often captures before content loads |
| **Cookie banners** | Auto-dismisses common consent banners | Left covering the page |
| **Formats** | PNG, JPEG, and paginated **PDF** | Usually PNG only |
| **Devices** | Desktop + mobile presets, or custom viewport | Fixed size |
| **Billing** | Pay per **successful** capture; failures are free | Charged regardless |

***

### Features

- 🖼 **PNG, JPEG, or PDF.** Full-page or viewport screenshots, or a paginated A4 PDF of the page.
- ⏳ **Smart waiting.** Choose `load`, `domcontentloaded`, or `networkidle`, and optionally wait for a CSS selector (a chart, a main element) before capturing.
- 🍪 **Cookie-banner dismissal.** Best-effort auto-close of common consent/cookie dialogs so they don't cover your shot.
- 📱 **Device presets.** Desktop 1920/1366, iPhone, iPad, or a custom width/height.
- 🔒 **Authenticated pages.** Pass cookies to capture pages behind a login (stored encrypted).
- 💬 **Actionable errors.** Timeouts, unreachable hosts, and missing selectors come back as clear codes, not stack traces.
- 💸 **Fair pricing.** One charge per successful capture. Navigation errors and timeouts cost nothing.

***

### Input

| Field | Required | Description |
|---|---|---|
| `url` | ✅ | Page to capture (include `https://`). |
| `format` | | `png` (default), `jpeg`, or `pdf`. |
| `fullPage` | | Capture the whole scrollable page (PNG/JPEG). Default `true`. |
| `device` | | `desktop_1920` (default), `desktop_1366`, `iphone`, `ipad`, or `custom`. |
| `width` / `height` | | Viewport size when `device = custom`. |
| `waitUntil` | | `load`, `domcontentloaded`, or `networkidle` (default). |
| `waitForSelector` | | Optional CSS selector to wait for before capturing. |
| `delayMs` | | Extra wait after ready, for late animations (max 30000). |
| `dismissCookieBanners` | | Auto-close consent banners. Default `true`. |
| `jpegQuality` | | 1–100, for `format = jpeg`. |
| `headers` / `cookies` | | Optional custom headers / auth cookies. |

#### Example — full-page PNG

```json
{ "url": "https://news.ycombinator.com", "format": "png", "fullPage": true }
```

#### Example — mobile screenshot, wait for content

```json
{
    "url": "https://example.com/report",
    "format": "jpeg",
    "device": "iphone",
    "waitForSelector": "#report-ready"
}
```

#### Example — PDF (A4 print output)

```json
{ "url": "https://example.com/invoice", "format": "pdf" }
```

PDF uses Chromium's print rendering (paginated A4), not a device-sized screenshot.

### Output

The captured file is stored in the run's key-value store (key `OUTPUT`), and a report is pushed to the dataset:

```json
{
    "type": "capture_report",
    "status": "SUCCEEDED",
    "url": "https://example.com",
    "format": "png",
    "assetUrl": "https://api.apify.com/v2/key-value-stores/.../records/OUTPUT.png",
    "widthPx": 1920,
    "heightPx": 1063,
    "bytes": 84213,
    "durationMs": 3120
}
```

### Error reference

| Code | Meaning |
|---|---|
| `INVALID_URL` | URL missing or not http(s) |
| `SSRF_BLOCKED` | Target is a private/internal address (blocked by default) |
| `NAVIGATION_TIMEOUT` | Page didn't finish loading in 60s |
| `DNS_OR_UNREACHABLE` | Host couldn't be reached |
| `SELECTOR_TIMEOUT` | `waitForSelector` never appeared |
| `OUTPUT_TOO_LARGE` | Full-page height over the limit (raise `maxFullPageHeightPx`) |
| `HTTP_ERROR` | Page returned 4xx/5xx and `failOnHttpError` is on |
| `RENDER_FAILED` / `NAVIGATION_FAILED` | Rendering or navigation error |

### Pricing

One pay-per-event charge **per successful capture**. Failed captures (timeouts, unreachable hosts) are **free**.

### FAQ

**The screenshot is missing content that loads late — what do I do?**
Use `waitUntil: networkidle` (the default), add a `waitForSelector` for the element you care about, or a small `delayMs`.

**Can it capture pages behind a login?**
Yes — pass session `cookies` (Playwright format). They're stored as a secret.

**Full-page or viewport?**
`fullPage: true` captures the entire scrollable page; set it to `false` for just the visible viewport.

# Actor input Schema

## `url` (type: `string`):

The page to screenshot or render to PDF. Include the protocol (https://). Public URLs only.

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

png (lossless), jpeg (smaller), or pdf (paginated document).

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

Capture the entire scrollable page (PNG/JPEG). Ignored for PDF.

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

Preset viewport. Choose 'custom' to set width/height below.

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

Viewport width when device = custom.

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

Viewport height when device = custom.

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

When to consider the page ready: load (all resources), domcontentloaded (fast), or networkidle (best for JS-heavy sites).

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

Optional CSS selector to wait for before capturing (e.g. a chart or main content).

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

Extra wait after the page is ready, for late animations. Max 30000.

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

Attempt to auto-close common cookie / consent banners before capturing.

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

Only used when format = jpeg.

## `maxFullPageHeightPx` (type: `integer`):

Fail instead of capturing full pages taller than this (protects memory). Default 20000.

## `failOnHttpError` (type: `boolean`):

By default the actor captures error pages too (and reports the status). Enable to fail instead so you are not charged for a 404/403 page.

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

Optional headers sent with the request (e.g. Authorization or a custom User-Agent). Stored encrypted.

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

Optional cookies for capturing pages behind a login. Array of Playwright cookie objects. Stored encrypted.

## Actor input object example

```json
{
  "url": "https://example.com",
  "format": "png",
  "fullPage": true,
  "device": "desktop_1920",
  "waitUntil": "load",
  "delayMs": 0,
  "dismissCookieBanners": true,
  "jpegQuality": 80,
  "maxFullPageHeightPx": 20000,
  "failOnHttpError": false
}
```

# Actor output Schema

## `report` (type: `string`):

Per-run report with the asset URL and metadata.

## `asset` (type: `string`):

The screenshot or PDF stored in the key-value store.

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

// Run the Actor and wait for it to finish
const run = await client.actor("amazing_wizdom/web-screenshot-capture").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 = { "url": "https://example.com" }

# Run the Actor and wait for it to finish
run = client.actor("amazing_wizdom/web-screenshot-capture").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "url": "https://example.com"
}' |
apify call amazing_wizdom/web-screenshot-capture --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=amazing_wizdom/web-screenshot-capture",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

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