# Website Screenshot and PDF Generator (`dektionstudio/website-screenshot-pdf`) Actor

Screenshots and PDFs of any web page from a list of URLs: full page or visible screen, desktop, tablet or mobile. Cookie banners closed, ads blocked, lazy images loaded. Each file comes back as a download link. $3 per 1,000 pages.

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

## Pricing

from $3.00 / 1,000 screenshot or pdfs

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 and PDF Generator

Turn a list of URLs into screenshots or PDFs: the full page or just the visible screen, as a desktop, laptop, tablet or phone would show it. Cookie banners are closed and ads are blocked before the capture, and every file comes back as a download link you can put in a report, an archive or a visual check, or hand to an AI agent that needs to see a page.

Getting a clean capture is the hard part. A screenshot with a cookie banner over half the page, or gray boxes where images should be, isn't much use for before and after shots for a client or proof of how a competitor's page looked on a given day. So the Actor clicks accept on the common consent tools (OneTrust, Cookiebot, Didomi, Usercentrics and more), hides other fixed privacy notices, and scrolls through the page so lazy images load.

### What you get for each page

- A PNG, JPEG or PDF file in the run's storage, with a link you can open or download
- The final URL after redirects, the HTTP status and the page title
- File size, load time, and whether a cookie banner was closed
- An error row with the reason for pages that couldn't be loaded, at no cost

### Input

```json
{
    "urls": ["https://apify.com", "https://en.wikipedia.org/wiki/Web_scraping"],
    "format": "png",
    "device": "desktop",
    "fullPage": true
}
```

- `format`: `png`, `jpeg` (smaller files, with `jpegQuality`) or `pdf` (A4 or Letter, backgrounds printed).
- `device`: desktop 1920 x 1080, laptop 1366 x 768, tablet (iPad size) or mobile (iPhone size). Tablet and mobile get a mobile browser, so sites show their mobile layout. `viewportWidth` and `viewportHeight` set any size you want.
- `fullPage`: the whole page top to bottom, or only the first screen.
- `selector`: capture one element instead of the page, for example `#pricing` or `.hero`.
- `darkMode` asks sites for their dark theme. `delayMs` waits longer for animations. `proxyConfiguration` is there for sites that block data centers or change content by country.

### Output

```json
{
    "url": "https://www.theverge.com",
    "status": "ok",
    "httpStatus": 200,
    "title": "The Verge",
    "fileUrl": "https://api.apify.com/v2/key-value-stores/.../records/0002-theverge.com.png",
    "format": "png",
    "device": "desktop",
    "bytes": 4232000,
    "loadMs": 2482,
    "bannerClosed": true,
    "cutAtPixels": null
}
```

The Images view shows the pictures right in the results table.

### Pricing

$0.003 per captured page, image or PDF, so 1,000 pages cost $3. Pages that fail to load are free. Apify adds $0.0001 per run for starting the Actor with its default 2 GB of memory. You can set a maximum charge per run and the Actor stops cleanly when it gets there.

### Speed

In test runs on 27 September a Wikipedia article loaded in 1 to 2 seconds and The Verge's home page on mobile in 5 to 6. The Actor captures 3 pages at a time, so 100 ordinary pages take a few minutes.

### Limits

- Full-page captures stop at 20,000 pixels tall. Very long pages, like endless news feeds, are cut there, and `cutAtPixels` tells you when that happened.
- Cookie banner handling covers the common consent tools and most home-made notices, not every site. If one stays, `bannerClosed` is false and a longer `delayMs` sometimes helps.
- Sites with strong bot protection may show a challenge page instead of the content. Try the residential proxy for those.
- Pages behind a login can't be captured.

### Changelog

- 2026-09-27: first version.

# Actor input Schema

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

Pages to capture, one per line. Up to 1,000 per run.

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

Image or PDF.

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

Screen size and browser type the page sees. Tablet and mobile get a mobile browser and sharper pixels.

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

Capture the whole page top to bottom. Off captures only what fits on the screen.

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

Clicks accept on common consent banners and hides any that are left.

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

Stops requests to the big ad networks, so pages load faster and look cleaner.

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

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

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

Wait this long after the page loads, for animations and late content.

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

When the page counts as loaded.

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

CSS selector of one element to capture instead of the page, for example #pricing or .hero. Images only.

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

Overrides the device width. 0 uses the device preset.

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

Overrides the device height. 0 uses the device preset.

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

Only for JPEG. Lower gives smaller files.

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

Only for PDF.

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

Give up on a page that takes longer than this. Failed pages are free.

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

Optional. Use a proxy for sites that block data centers or show different content per country.

## Actor input object example

```json
{
  "urls": [
    "https://apify.com",
    "https://en.wikipedia.org/wiki/Web_scraping"
  ],
  "format": "png",
  "device": "desktop",
  "fullPage": true,
  "hideCookieBanners": true,
  "blockAds": true,
  "darkMode": false,
  "delayMs": 1000,
  "waitUntil": "load",
  "viewportWidth": 0,
  "viewportHeight": 0,
  "jpegQuality": 80,
  "pdfFormat": "A4",
  "timeoutSecs": 60
}
```

# Actor output Schema

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

No description

## `summary` (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": [
        "https://apify.com",
        "https://en.wikipedia.org/wiki/Web_scraping"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("dektionstudio/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": [
        "https://apify.com",
        "https://en.wikipedia.org/wiki/Web_scraping",
    ] }

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

```

## MCP server setup

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