# Website Screenshot & PDF API - Full Page, Mobile, No Popups (`markup/website-screenshot-api`) Actor

Turn any list of URLs into full-page screenshots (PNG/JPEG) or PDFs. Desktop, laptop, tablet and mobile presets, cookie banners hidden, lazy images loaded, optional page text for AI agents. Pay only per successful screenshot.

- **URL**: https://apify.com/markup/website-screenshot-api.md
- **Developed by:** [Bennett Love](https://apify.com/markup) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 screenshots

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

## Website Screenshot & PDF API

Turn a list of URLs into **full-page screenshots (PNG or JPEG) or PDFs** in one run. Cookie banners are hidden, lazy images are loaded, and you get desktop, laptop, tablet or mobile views. **You pay only for screenshots that succeed.** Failed or timed-out pages cost nothing.

Built for AI agents and automations. Each result has a public image URL, the page title, the HTTP status, and optionally the page's visible text, so an agent can **see and read a page in one call**.

### What you get

```json
{
  "url": "https://example.com/pricing",
  "finalUrl": "https://example.com/pricing",
  "ok": true,
  "statusCode": 200,
  "title": "Pricing | Example",
  "screenshotUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/0-example.com-1a2b3c4d",
  "format": "png",
  "device": "desktop",
  "width": 1920,
  "height": 4210,
  "fullPage": true,
  "truncated": false,
  "bytes": 912345,
  "text": "Plans for every team ... (only when includeText is on)",
  "capturedAt": "2026-10-18T14:03:11.000Z"
}
```

A failed page returns `"ok": false` with an `error` message. It is not charged.

### Use cases

- **AI agents:** visual checks of a page, UI review, "what does this site look like right now".
- **Monitoring:** daily full-page snapshots of competitor pricing or landing pages, run on a schedule.
- **QA:** check a design on desktop, tablet and mobile in one batch.
- **Archiving and compliance:** PDF or PNG proof of what a page showed and when.
- **Reports and decks:** clean screenshots with no cookie popups.

### Features

| | |
|---|---|
| Full page or first screen | Long pages are cut at a height you choose (default 15,000 px) and flagged `truncated` |
| Devices | desktop 1920×1080, laptop 1366×768, tablet 820×1180 @2x, mobile 390×844 @3x (iPhone user agent), or a custom width and height |
| Formats | PNG, JPEG (quality setting), PDF (A4, with backgrounds) |
| Clean shots | Hides OneTrust, Cookiebot, Didomi, Quantcast, Usercentrics, TrustArc, Osano, CookieYes, Complianz and other consent popups **without clicking accept**. Add your own selectors to hide chat widgets and the like |
| Hard pages | Wait for a CSS selector, choose the load event (`load`, `domcontentloaded`, `networkidle`), add a delay, scroll to load lazy images, dark mode |
| Element shots | Capture only one element, e.g. `#pricing` |
| Text for LLMs | `includeText` returns the page's visible text, capped at `maxTextChars` |
| Batch | Runs pages in parallel, retries failed pages, and works with an optional Apify Proxy |
| Budget-safe | Respects your *max cost per run* and stops before going over |

### Pricing

Pay per event:

- **Screenshot**: about **$3 per 1,000** successful screenshots or PDFs. Volume tiers are cheaper.
- **Actor start**: a small fee per run, which covers starting the browser.

There is no charge for pages that fail. Platform usage is included.

### Input example

```json
{
  "urls": ["https://apify.com", "news.ycombinator.com"],
  "device": "mobile",
  "fullPage": true,
  "format": "png",
  "hideCookieBanners": true,
  "includeText": true
}
```

### Using it from an AI agent (MCP)

This actor works with the [Apify MCP server](https://mcp.apify.com). Agents can find it with the search tool and call it with `urls`. The result's `screenshotUrl` is a direct image link that vision models can open. It uses pay-per-event pricing without Standby, so agents can also pay per call where Apify supports agent payments.

### Tips

- If a site loads content late, set `waitUntil: "networkidle"` or a `waitForSelector`.
- For sites that block data-center traffic, turn on a proxy in *Proxy*.
- For a large batch, raise *Parallel pages* and run with 4 GB of memory.

### Limits and fair use

The actor captures public pages that need no login. Only capture pages you are allowed to access, and follow each site's terms. Images are stored in the run's key-value store and follow your Apify data retention settings.

### Feedback

Found a page that renders badly? Open an issue on the Issues tab with the URL and your input.

# Actor input Schema

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

Pages to capture. https:// is added if missing. You are charged only for pages that are captured successfully.

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

Viewport preset. desktop = 1920x1080, laptop = 1366x768, tablet = 820x1180 (2x), mobile = 390x844 (3x, iPhone user agent).

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

Capture the whole scrollable page instead of only the first screen.

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

png (sharp, larger), jpeg (smaller) or pdf (A4, printable, selectable text).

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

Hide common consent popups (OneTrust, Cookiebot, Didomi, Quantcast, Usercentrics, TrustArc, CookieYes and more) without clicking accept.

## `includeText` (type: `boolean`):

Also return the page's visible text, so an AI agent can see and read the page in one call.

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

Ask the site for its dark color scheme (prefers-color-scheme: dark).

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

Overrides the device preset width.

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

Overrides the device preset height.

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

Screenshot just the first element matching this selector, e.g. #pricing or main.

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

Wait until this CSS selector appears before capturing.

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

Extra elements to hide, e.g. chat widgets or sticky headers.

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

When the page counts as loaded. networkidle is slowest but safest for heavy JavaScript sites.

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

Wait this long after loading, before capturing (animations, fonts).

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

Scroll through the page first so lazy-loaded images appear in full-page shots.

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

Very long pages are cut at this height (the result is flagged truncated).

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

1-100, only used for jpeg.

## `maxTextChars` (type: `integer`):

Cap on returned page text.

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

Pages captured at the same time. Raise memory for higher values.

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

Give up on a page after this many seconds.

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

Extra attempts for a page that fails to load. Failed pages are not charged.

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

Optional. Use a proxy for sites that block data-center traffic or to capture from another country.

## Actor input object example

```json
{
  "urls": [
    "https://apify.com",
    "https://news.ycombinator.com"
  ],
  "device": "desktop",
  "fullPage": true,
  "format": "png",
  "hideCookieBanners": true,
  "includeText": false,
  "darkMode": false,
  "waitUntil": "load",
  "delayMs": 500,
  "scrollToBottom": true,
  "maxFullPageHeight": 15000,
  "jpegQuality": 80,
  "maxTextChars": 20000,
  "maxConcurrency": 4,
  "pageTimeoutSecs": 45,
  "maxRetries": 1
}
```

# Actor output Schema

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

Rows with url, ok, title, statusCode, screenshotUrl, width, height and optional text.

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

The PNG, JPEG or PDF files.

# 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://news.ycombinator.com"
    ]
};

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

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

```

## MCP server setup

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