# Website Screenshot API (Full Page, Mobile, PDF) (`locaihost/screenshot`) Actor

Capture screenshots or PDFs of up to 5,000 web pages or your own HTML per run. Each row gives a public image link, final URL, HTTP status, title, file size and the cookie banner it closed. Full page, one element, 11 device presets, dark mode. Failed pages free. $0.89 per 1,000 screenshots.

- **URL**: https://apify.com/locaihost/screenshot.md
- **Developed by:** [locaihost data](https://apify.com/locaihost) (community)
- **Categories:** Developer tools, SEO tools, Automation
- **Stats:** 5 total users, 4 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.89 / 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 API (Full Page, Mobile, PDF)

Turn up to 5,000 URLs, or your own HTML, into PNG, JPEG, WebP or PDF files in one run, each with a public link, from a fresh browser that closes known cookie banners and blocks ads. No login, no API key.

- **Monitor pages visually:** schedule a daily run of your own or competitors' pages and keep a dated archive of how they looked.
- **Client and SEO reports:** batch-capture landing pages, ad destinations or search result pages for a report.
- **Render your own HTML:** social cards, invoices, certificates and email previews, sent as HTML and returned as an image or PDF.
- **QA across devices:** check pages on iPhone, Pixel, Galaxy, iPad and desktop presets, in light and dark mode.
- **Archive and evidence:** save pages as PDFs with selectable text, with the time each was taken.

### Quick start

Paste this into the **JSON** tab of the input and click **Start**:

```json
{"urls": ["https://www.wikipedia.org", "https://news.ycombinator.com", "https://example.com"], "viewport": "desktop", "format": "png"}
```

You get 3 rows, each with a link to a 1440×900 PNG, in about 25 seconds (most of that is the browser starting). Bare domains like `example.com` work without `https://`, and duplicates are removed.

To render your own HTML as a 1200×630 social card:

```json
{
    "html": "<html><body style='margin:0;background:#0b3d2e;color:#fff;font:64px sans-serif;display:grid;place-items:center;height:630px'>Hello from my app</body></html>",
    "viewport": "custom",
    "viewportWidth": 1200,
    "viewportHeight": 630
}
```

### What data can I get?

![Real records from this Actor's output: public pages captured at desktop size, with HTTP status, image size, the cookie banner it handled and the file link](https://locaihost.org/img/readme/screenshot.png)

One dataset row per page. The file itself sits in the run's key-value store, and `screenshotUrl` is its public link.

| Group | Fields |
|---|---|
| Page | `index` (position in your input), `source` (`url` or `html`), `url`, `finalUrl` (after redirects), `status` (HTTP code), `title` |
| File | `screenshotUrl`, `key`, `format`, `width`, `height` (null for PDF), `bytes` |
| Capture | `fullPage` (charged at the full-page price), `truncated` (page taller than `maxHeight`), `cookieBanner` (the consent platform it handled), `takenAt` |
| Errors | `error` (why a page failed; null on success) |

One real row (run on 2026-10-18, signature shortened):

```json
{
  "index": 0,
  "source": "url",
  "url": "https://www.wikipedia.org/",
  "finalUrl": "https://www.wikipedia.org/",
  "status": 200,
  "title": "Wikipedia",
  "screenshotUrl": "https://api.apify.com/v2/key-value-stores/83DeOGbJoTHAld34l/records/0001-wikipedia-org-72e64cab.png?signature=…",
  "key": "0001-wikipedia-org-72e64cab.png",
  "format": "png",
  "width": 1440,
  "height": 900,
  "bytes": 251454,
  "fullPage": false,
  "truncated": false,
  "cookieBanner": null,
  "takenAt": "2026-10-18T05:38:36.949Z",
  "error": null
}
```

The **Overview** view shows each screenshot as a thumbnail next to its URL, status and size. Export the rows to JSON, CSV, Excel or HTML, or fetch the files through the Apify API. The run's `SUMMARY` record counts pages captured, failed and not run, lists invalid inputs, and says why the run stopped.

**What you can control:**

- **Area:** first screen (default), full page (`fullPage`), one element (`selector`, e.g. `#pricing`) or an exact rectangle (`clip`, which can reach below the first screen).
- **Device:** 11 presets with real screen size, pixel density, touch and mobile user agent (Desktop 1440×900, Full HD 1920×1080, Laptop 1366×768, MacBook Pro 14", iPhone 15/16, iPhone SE, iPhone 16 Pro Max, Pixel 8, Galaxy S24, iPad Air, iPad Pro 12.9"), or a custom size from 240 to 3840 px wide, at up to 3× density.
- **Format:** PNG, JPEG or WebP (with `quality`, and a transparent background option for PNG and WebP), or PDF in A4, Letter, A3 or Legal.
- **Clean-up:** cookie banners (it clicks a button only inside 19 known consent platforms such as OneTrust, Cookiebot, Didomi, Quantcast, Usercentrics and TrustArc, preferring "reject", and hides the banners of about 30 platforms plus common cookie-banner elements; buttons on unknown banners are never clicked), ad and tracker blocking (on by default), `hideSelectors`, `blurSelectors` to redact parts of a page, and `customCss`.
- **Timing:** `waitForSelector` for single-page apps, `waitUntil`, `delayMs`, and `timeoutSecs` (each page is retried once on a timeout or dropped connection).
- **Browser:** `darkMode`, `locale` (e.g. `de-DE`), `timezone` (e.g. `Asia/Tokyo`) and `userAgent`.

API callers can also send a single `url`, `device` names such as `iphone_15`, `pixel_7` or `galaxy_s23`, and `colorScheme: "dark"`.

### How much does it cost?

You pay per screenshot taken. There is no charge for Apify platform usage on top.

| Row | Free and Starter | Scale | Business |
|---|---|---|---|
| Screenshot (first screen, element, region, your own HTML, or a PDF) | $0.89 per 1,000 | $0.89 per 1,000 | $0.89 per 1,000 |
| Full-page screenshot of a web page (`fullPage` on) | $2.00 per 1,000 | $2.00 per 1,000 | $2.00 per 1,000 |

Plus $0.00005 per run start. **Apify's free $5 monthly credit covers about 5,600 screenshots** (or about 2,500 full-page ones). Free-plan runs stop at 50 screenshots each, and the log says how many pages were not run; any paid Apify plan removes the cap.

With `fullPage` on, element and region captures, HTML documents and PDFs are still charged as a normal screenshot. Each row's `fullPage` field shows which price applied. Format, device and quality don't change the price.

**What's free:** pages that fail (timeouts, DNS errors, a missing `selector` or `waitForSelector` element, direct file links), invalid URLs, duplicates, and pages not reached before the run's time limit. A page that loads with an error status, such as a 404 page, is captured and charged, because you get its screenshot; its `status` shows the code. To cap a run's spend, set **Maximum cost per run** in the run options: the run stops cleanly and never starts a page it can't charge for.

### Limits, stated up front

- Up to 5,000 URLs and 100 HTML documents per run (each HTML document up to 5,000,000 characters). Extra URLs are skipped and counted in `SUMMARY`.
- Full-page captures stop at `maxHeight` (16,000 CSS pixels by default) and never go past the 16,383-pixel image limit divided by the scale factor. Those rows have `truncated: true`. Use PDF for longer pages.
- Login-only or bot-protected pages are captured as the public sees them: a login page, or a challenge page if the site blocks automated browsers. This Actor does not get around logins or bot protection.
- WebGL (3D scenes, some maps and charts) is off by default because software rendering is slow; most sites show a normal fallback. Turn on `webgl` for pages that need it.
- Pages run 3 at a time at the default 2 GB memory (2 at a time for full-page and PDF captures). More memory runs more pages in parallel, up to 8, at the same price per screenshot.
- If the run's time limit is reached, it stops cleanly, keeps what it captured and counts the rest as not run (not charged).
- Files are kept for your Apify plan's storage retention period. Copy them to your own storage if you need them longer.

### Schedules

Save your URL list as a task, then add a daily or weekly schedule under **Schedules** in Apify Console. Each run captures every page fresh, so you build a dated visual archive; `takenAt` records the exact time of each capture.

### Integrations: API, n8n, Make and AI agents

**API.** Run it and get the rows back in one call (synchronous runs wait up to 5 minutes; use the asynchronous run endpoint for large batches):

```bash
curl -X POST "https://api.apify.com/v2/acts/locaihost~screenshot/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://example.com", "https://www.wikipedia.org"], "format": "webp", "quality": 75}'
```

Python, with `pip install apify-client`:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("locaihost/screenshot").call(run_input={"urls": ["https://example.com"], "fullPage": True})
for shot in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(shot["url"], shot["status"], shot["screenshotUrl"] or shot["error"])
```

**n8n, Make, Zapier, Google Sheets, Slack, webhooks.** Apify's built-in integrations send each run's rows, with their image links, wherever you need them.

**AI agents (MCP).** Add this Actor to Claude, Cursor or any MCP client with `https://mcp.apify.com/?tools=locaihost/screenshot`, then ask something like *"Take a mobile screenshot of the pricing section on example.com and tell me which plans are shown."* The agent gets back a `screenshotUrl` it can open or pass to a vision model. A minimal agent input is `{"url": "https://example.com", "device": "iphone_15", "selector": "#pricing"}`.

### FAQ

#### How much does it cost to screenshot a website?

$0.89 per 1,000 screenshots and $2.00 per 1,000 full-page screenshots, the same on every Apify plan. Failed pages are free. Apify's free $5 monthly credit covers about 5,600 screenshots.

#### Can I use it through the API or from Python?

Yes. Use the `run-sync-get-dataset-items` call above, or Apify's Python and JavaScript clients. Every run's rows are also available as JSON, CSV or Excel from its dataset.

#### Can I use it from an AI agent?

Yes. Through the Apify MCP server (`https://mcp.apify.com/?tools=locaihost/screenshot`) any MCP client can send a URL and read back the image link.

#### Is it legal to screenshot websites?

The Actor loads public pages the way any visitor's browser does. It never logs in and does not get around bot protection. The dataset records technical facts (URL, status, title, size) and the image, and a screenshot shows whatever the page shows, so avoid pages that display other people's personal details, or blur them with `blurSelectors`. You are responsible for having the right to capture and use each page, and for following each site's terms.

#### Does it accept cookie banners for me?

It prefers "reject". It clicks a button only inside a consent platform it recognises, hides banners it can't close, and never clicks buttons on banners it doesn't recognise. `cookieBanner` names the platform it handled.

#### Why are some fields empty?

`width` and `height` are null for PDFs. A failed page has no file: `screenshotUrl` is null and `error` says why, for example `Timeout 45000ms exceeded`, `Element not found or not visible: #pricing` or a DNS error such as `net::ERR_NAME_NOT_RESOLVED`. `cookieBanner` is null when no known banner appeared. HTML input has `url` null and `source: "html"`.

#### A page timed out or shows a "verify you are human" page. What can I do?

Raise `timeoutSecs`, give the run more memory, or set `waitUntil` to `domcontentloaded`. A challenge or login page means the site blocks automated browsers or needs an account; this Actor captures it as it is and does not try to get around it.

### More from locaihost data

- [Document to Markdown converter](https://apify.com/locaihost/doc-to-markdown): turn the same pages, PDFs and Office files into clean Markdown text.
- [OCR for images and scanned PDFs](https://apify.com/locaihost/ocr): read the text out of images and scans.
- [SEO site audit](https://apify.com/locaihost/site-audit): page-level SEO checks for the sites you capture.
- [Website traffic checker](https://apify.com/locaihost/website-traffic): monthly visits and traffic sources for a list of domains.

### Did it help?

If this saved you time, a quick rating on the Store helps other people find it.

### Support

Something not working, a page that doesn't capture well, or a cookie banner we don't close? Open an issue on the **Issues** tab with the URL: we answer issues within 24 hours.

# Changelog

This Actor's version history is a separate document: https://apify.com/locaihost/screenshot/changelog.md

# Actor input Schema

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

One web page per line, up to 5,000 per run. Bare domains like example.com get https:// added. Duplicates are removed; invalid entries are listed in the output with an error and never charged. Leave empty if you only want to render HTML below. (API callers can also send a single "url".)

## `html` (type: `string`):

Optional. Paste a full HTML document (inline CSS, images by absolute URL or data URI) and get it back as an image or PDF, e.g. for social cards, invoices or email previews. Max 5,000,000 characters. For several documents, use HTML documents below.

## `htmlDocuments` (type: `array`):

Optional list of up to 100 HTML documents, one image or PDF each, rendered after the URLs and the HTML field above. Example: \["<h1>One</h1>", "<h1>Two</h1>"].

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

PNG is lossless and sharp. JPEG and WebP are much smaller (set Quality below). PDF prints the page as a searchable, selectable document.

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

Capture the whole scrollable page instead of just the first screen. Very tall pages stop at Max height. Full-page captures of web pages are charged as a full-page screenshot ($2.00 per 1,000 instead of $0.89), because they take about twice the computing. Element, region, HTML and PDF captures stay at $0.89.

## `viewport` (type: `string`):

Desktop and laptop sizes, or a real phone or tablet: its screen size, pixel density, touch and mobile user agent, so sites serve their phone layout. Custom uses the width and height below. API callers can also send "device" with names like iphone_15, pixel_7, galaxy_s23 or ipad.

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

Optional. Screenshot just the first element matching this selector, e.g. #pricing, main, .hero. If it isn't on the page, that URL gets an error and is not charged.

## `clip` (type: `object`):

Optional rectangle in CSS pixels from the page's top-left: {"x": 0, "y": 0, "width": 1200, "height": 630}. It can reach below the first screen. Ignored when an element selector is set.

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

Used only when Device is Custom. 240–3840.

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

Used only when Device is Custom. 240–8000. With Full page on, this is just the window height; the image grows to the page.

## `deviceScaleFactor` (type: `number`):

Pixel density: 2 gives retina-sharp images at twice the width and height. 0 = the device's own (1 for desktop/laptop, 2 tablet, 3 mobile). Max 3.

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

Full-page captures stop at this many CSS pixels (and never beyond the 16,383-pixel image limit, divided by the scale factor). Taller pages are cut and marked truncated.

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

Close or hide consent banners from ~30 known consent platforms (OneTrust, Cookiebot, Didomi, Quantcast, Usercentrics, TrustArc and more), preferring 'reject'. Buttons on unknown banners are never clicked.

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

Block requests to common ad, analytics and tracking domains (on by default). Cleaner, faster captures; turn off if you need the page exactly as visitors see it, ads included.

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

Optional CSS selectors to hide before capturing, e.g. a chat widget (#intercom-container) or a promo bar (.announcement-bar).

## `blurSelectors` (type: `array`):

Optional CSS selectors to blur in place (layout unchanged), e.g. to redact emails, prices or account numbers in shared screenshots.

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

Ask the page for its dark theme (prefers-color-scheme: dark). Sites without a dark theme look the same.

## `blockImages` (type: `boolean`):

Don't load images. Faster, lighter captures of text and layout.

## `blockMedia` (type: `boolean`):

Don't load video and audio files. Saves time on pages with autoplay video.

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

Optional CSS injected before capturing, e.g. body { font-size: 18px }. Max 20,000 characters.

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

When the page counts as loaded. Load is the default and suits most sites. Network idle also waits (up to 3 s) for late requests to finish; DOM ready is fastest. Pages that never settle are still captured when the timeout runs out.

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

Optional CSS selector. Capture only once it is visible, e.g. #app .loaded or .chart canvas. Useful for single-page apps. If it never appears within the timeout, that page gets an error and is not charged.

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

Wait this long after loading, before capturing. Useful for animations, charts and slow widgets. 0–60000.

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

Give up on a page that hasn't started loading within this time. Timeouts are retried once. 5–180.

## `scrollToLoad` (type: `boolean`):

Scroll through the page before a full-page or element capture so lazy-loaded images and sections appear.

## `reduceMotion` (type: `boolean`):

Ask pages to skip animations (prefers-reduced-motion), the way a visitor with that accessibility setting sees them. Faster and steadier captures; turn off to capture animated sites mid-motion.

## `webgl` (type: `boolean`):

Turn on for pages built on WebGL: 3D scenes, some maps and charts. Off by default because software WebGL is slow; most sites show a normal fallback without it.

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

1–100. Higher is sharper and bigger. Ignored for PNG and PDF.

## `transparentBackground` (type: `boolean`):

Pages without their own background colour come out transparent instead of white. PNG and WebP only.

## `pdfPageSize` (type: `string`):

Paper size when Format is PDF.

## `locale` (type: `string`):

Optional, e.g. en-GB, de-DE, ja-JP. Sets the browser's language, so sites that follow it show that version. Default en-US.

## `timezone` (type: `string`):

Optional IANA name, e.g. Europe/London or America/New_York. Changes the times and dates pages show.

## `userAgent` (type: `string`):

Optional. Replaces the browser's (or the device preset's) User-Agent string.

## Actor input object example

```json
{
  "urls": [
    "https://www.wikipedia.org",
    "https://news.ycombinator.com",
    "https://example.com"
  ],
  "format": "png",
  "fullPage": false,
  "viewport": "desktop",
  "viewportWidth": 1440,
  "viewportHeight": 900,
  "deviceScaleFactor": 0,
  "maxHeight": 16000,
  "hideCookieBanners": true,
  "blockAds": true,
  "darkMode": false,
  "blockImages": false,
  "blockMedia": false,
  "waitUntil": "load",
  "delayMs": 0,
  "timeoutSecs": 45,
  "scrollToLoad": true,
  "reduceMotion": true,
  "webgl": false,
  "quality": 80,
  "transparentBackground": false,
  "pdfPageSize": "A4"
}
```

# Actor output Schema

## `screenshots` (type: `string`):

One record per URL: public file link, final URL, HTTP status, title, size and any error (overview view).

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

The key-value store holding every screenshot and PDF.

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

Counts of captured, failed and skipped URLs, invalid inputs and why the run stopped.

# 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://www.wikipedia.org",
        "https://news.ycombinator.com",
        "https://example.com"
    ],
    "format": "png",
    "viewport": "desktop"
};

// Run the Actor and wait for it to finish
const run = await client.actor("locaihost/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://www.wikipedia.org",
        "https://news.ycombinator.com",
        "https://example.com",
    ],
    "format": "png",
    "viewport": "desktop",
}

# Run the Actor and wait for it to finish
run = client.actor("locaihost/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://www.wikipedia.org",
    "https://news.ycombinator.com",
    "https://example.com"
  ],
  "format": "png",
  "viewport": "desktop"
}' |
apify call locaihost/screenshot --silent --output-dataset

```

## MCP server setup

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