# Website Screenshot & PDF – Full Page, Mobile, Bulk URLs (`pinkish_armada/website-screenshot`) Actor

Capture full-page or viewport screenshots (PNG/JPEG) and PDFs of any list of URLs on desktop, laptop, tablet and mobile. Hides cookie banners, lazy-loads images, element screenshots, dark mode. $2 per 1,000 captures.

- **URL**: https://apify.com/pinkish_armada/website-screenshot.md
- **Developed by:** [Phuc Tiet](https://apify.com/pinkish_armada) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 captured screenshots

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/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, Bulk URLs

**Capture pixel-perfect screenshots and PDFs of any number of web pages — full page or viewport, on desktop, laptop, tablet and mobile — with cookie banners hidden and lazy images loaded.** Every file gets a shareable link, and every row tells you the page title, HTTP status and page height. Perfect for website monitoring, visual archives, client reports, design QA, SEO audits, compliance evidence and AI vision pipelines.

- 📸 **Full-page or viewport** screenshots in **PNG** or **JPEG** (adjustable quality)
- 📄 **PDF export** (A4, Letter, Legal, A3, Tabloid; portrait/landscape; print or screen styles)
- 📱 **Devices:** desktop 1920×1080, laptop 1366×768, tablet (iPad @2x), mobile (iPhone @3x) or any custom size — capture every URL on several devices in one run
- 🍪 **Clean captures:** hides 50+ cookie-consent popups (OneTrust, Cookiebot, Usercentrics, Didomi, Quantcast, CookieYes, Complianz, Termly, Osano …) via CSS — consent is never clicked — plus any elements you list
- 🖼️ **Lazy-loading handled:** scrolls the page first so images below the fold appear
- 🎯 **Element screenshots:** capture just `#pricing`, a chart or a hero section with a CSS selector
- 🌙 **Dark mode** emulation, configurable delay and load event
- 🔗 **Shareable links** for every file; optional named store to keep files long-term
- 💸 **$2 per 1,000 captures** — failed pages (404, DNS, timeouts) are free

### Pricing

Pay-per-event — you pay only for files actually produced:

| Event | Price |
|---|---|
| Captured screenshot | **$0.002** ($2 per 1,000) |
| Generated PDF | **$0.002** ($2 per 1,000) |

Examples: 500 URLs × desktop + mobile screenshots = 1,000 captures = **$2**. A daily screenshot of 20 competitor homepages ≈ **$1.20 / month**.

Similar screenshot Actors in the Apify Store charge from about $0.004 to $0.016 per screenshot (October 2026), and PDF export is rarely included. Pages that fail to load are never charged; set **Maximum cost per run** to cap spending.

### Quick start

```json
{
  "urls": ["https://apify.com", "https://en.wikipedia.org/wiki/Web_scraping"],
  "devices": ["desktop", "mobile"],
  "outputs": ["screenshot", "pdf"],
  "fullPage": true,
  "format": "jpeg"
}
```

### Output

One dataset row per URL × device:

```json
{
  "url": "https://example.com/",
  "device": "desktop",
  "status": "ok",
  "httpStatus": 200,
  "finalUrl": "https://example.com/",
  "title": "Example Domain",
  "pageHeight": 1080,
  "screenshotUrl": "https://api.apify.com/v2/key-value-stores/…/records/example.com-desktop-c54ea8.jpg?signature=…",
  "screenshotKey": "example.com-desktop-c54ea8.jpg",
  "screenshotBytes": 64115,
  "pdfUrl": "https://api.apify.com/v2/key-value-stores/…/records/example.com-desktop-c54ea8.pdf?signature=…",
  "capturedAt": "2026-10-07T05:20:00.000Z"
}
```

The **Captures** view shows image previews right in Apify Console. Failed pages produce a row with `status: "error"` and an `errorCode` (`HTTP_404`, `DNS_ERROR`, `TLS_ERROR`, `TIMEOUT`, `CONNECTION_ERROR`, `SELECTOR_NOT_FOUND`, `INVALID_URL` …). Files live in the run's key-value store (or the named store you choose), downloadable individually or via the API.

### Options

| Option | Default | Notes |
|---|---|---|
| `outputs` | screenshot | `screenshot`, `pdf` or both |
| `devices` | desktop | desktop, laptop, tablet, mobile, custom |
| `fullPage` | true | whole page vs visible viewport |
| `format` / `jpegQuality` | png / 80 | JPEG is 3–10× smaller |
| `hideCookieBanners` | true | CSS-hide common consent popups |
| `hideSelectors` | – | e.g. chat widgets, sticky bars |
| `selector` | – | capture a single element |
| `delaySecs` | 1 | wait after load |
| `waitUntil` | load | load / domcontentloaded / networkidle |
| `scrollToBottom` | true | trigger lazy-loaded images |
| `darkMode` | false | prefers-color-scheme: dark |
| `maxFullPageHeight` | 15000 px | very long pages are cut |
| `pdfFormat` / `pdfLandscape` / `pdfPrintBackground` / `pdfUseScreenCss` | A4 / false / true / false | PDF layout |
| `keyValueStoreName` | – | keep files in a named store (not deleted with the run) |
| `maxConcurrency` | 3 | parallel pages |

### Use cases

- **Website & competitor monitoring:** schedule daily captures of pricing pages and homepages; compare visually over time
- **Client reporting & agencies:** before/after shots of redesigns, ads landing pages, SEO work
- **Responsive design QA:** check desktop, tablet and mobile layouts of hundreds of URLs at once
- **Compliance & evidence:** timestamped captures of terms, disclosures and published content
- **Archiving & PDFs:** save articles, documentation and invoices-as-web-pages as PDF
- **AI vision & thumbnails:** feed screenshots into multimodal LLMs or generate link previews

### Integrations & API

Run it on a **schedule**, get files in **Google Drive / Dropbox / S3** via Make, Zapier or n8n, or call it from code:

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

AI agents can call it as a tool through the **Apify MCP server**.

### FAQ

**Can it screenshot pages behind a login?** No — public pages only.

**Does it bypass bot protection or CAPTCHAs?** No. Sites that block automated browsers return an error row (not charged).

**Why does the top of a page look empty?** Some sites reserve space for ads or load content only after interaction. Increase `delaySecs`, use `waitUntil: "networkidle"`, or hide the area with `hideSelectors`.

**Why are some PDFs large?** PDFs embed the page's images at full resolution; image-heavy news pages can produce 20–50 MB files. Turn off `pdfPrintBackground` or use JPEG screenshots for smaller output.

**How long are files kept?** Default run storage follows your Apify plan's data retention; use `keyValueStoreName` to keep files indefinitely.

### Related Actors

- **On-Page SEO Audit** — titles, meta tags, headings and schema for the same URLs
- **Broken Link Checker** — find dead links across a website
- **Sitemap URL Extractor** — get every URL of a site to capture

# Actor input Schema

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

Pages to capture. Each URL is captured once per selected device.

## `outputs` (type: `array`):

Screenshot (image), PDF, or both. Each file is charged separately.

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

Desktop 1920×1080, laptop 1366×768, tablet (iPad 820×1180 @2x), mobile (iPhone 390×844 @3x) or custom (set width/height below). Select several to capture each URL on every device.

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

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

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

PNG (lossless) or JPEG (smaller files).

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

1–100, only for JPEG.

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

Hide common cookie-consent popups (OneTrust, Cookiebot, Usercentrics, Didomi, Quantcast, CookieYes, Complianz and many more) via CSS. Consent is never clicked.

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

Extra elements to hide, e.g. chat widgets or sticky headers: "#intercom-container", ".sticky-header".

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

Screenshot a single element (e.g. "#pricing" or "main") instead of the page.

## `delaySecs` (type: `number`):

Extra wait after the page has loaded, for animations and late content.

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

Page load event to wait for. networkidle is the most complete but slower.

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

Scroll through the page before a full-page capture so lazy-loaded images appear.

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

Emulate prefers-color-scheme: dark.

## `maxFullPageHeight` (type: `integer`):

Very long pages are cut at this height.

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

Viewport width for the custom device.

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

Viewport height for the custom device.

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

1 = normal, 2 = retina (custom device only).

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

Paper size for PDF output.

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

Landscape orientation for PDFs.

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

Include background colours and images in PDFs (larger files).

## `pdfUseScreenCss` (type: `boolean`):

Render the PDF with screen styles instead of the site's print stylesheet.

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

Name of a key-value store to keep files beyond the default retention, e.g. "my-screenshots". Default: the run's own store.

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

Pages captured in parallel.

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

Navigation and capture timeout per page.

## Actor input object example

```json
{
  "urls": [
    "https://apify.com",
    "https://en.wikipedia.org/wiki/Web_scraping"
  ],
  "outputs": [
    "screenshot"
  ],
  "devices": [
    "desktop"
  ],
  "fullPage": true,
  "format": "png",
  "jpegQuality": 80,
  "hideCookieBanners": true,
  "delaySecs": 1,
  "waitUntil": "load",
  "scrollToBottom": true,
  "darkMode": false,
  "maxFullPageHeight": 15000,
  "viewportWidth": 1280,
  "viewportHeight": 800,
  "deviceScaleFactor": 1,
  "pdfFormat": "A4",
  "pdfLandscape": false,
  "pdfPrintBackground": true,
  "pdfUseScreenCss": false,
  "maxConcurrency": 3,
  "timeoutSecs": 60
}
```

# Actor output Schema

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

Screenshot previews, PDF links, page titles and status.

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

All screenshot and PDF files of this run.

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

Counts of screenshots, PDFs and errors.

# 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"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("pinkish_armada/website-screenshot").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",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("pinkish_armada/website-screenshot").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"
  ]
}' |
apify call pinkish_armada/website-screenshot --silent --output-dataset

```

## MCP server setup

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

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/7GPU6NVYsDTxDgCc5/builds/0AoOty3XCnqeH1suj/openapi.json
