# Website Screenshot API — URL & HTML to PNG, JPEG, WebP, PDF (`moonweil/url-screenshot-api`) Actor

Turn any URL or raw HTML into a screenshot, PDF, or Open Graph card. Full-page & device capture, dark mode, ad/tracker/cookie-banner blocking, visual diffing, base64-to-image conversion, and DOM + console-error extraction — all through one fast API.

- **URL**: https://apify.com/moonweil/url-screenshot-api.md
- **Developed by:** [Aleksandr Jelohhin](https://apify.com/moonweil) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 11 total users, 9 monthly users, 98.5% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 results

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 API 📸

Turn any **URL or raw HTML** into a pixel-perfect **screenshot, PDF, or Open Graph card**.
Full-page & device capture, dark mode, ad/tracker/cookie-banner blocking, PII redaction,
visual diffing, base64-to-image conversion, and DOM + console-error extraction — all in a
single run.

### Four tools in one Actor

Pick a **Mode** and get exactly one result per run — every mode is billed the same
(one result = one charge):

| Mode | What you get | Key inputs |
|---|---|---|
| **`screenshot`** (default) | PNG / JPEG / WebP / Chrome-rendered PDF of any URL **or raw HTML** | `url` or `html`, `format`, `fullPage`, `device` |
| **`og`** | Branded 1200×630 Open Graph / social-share card — no URL needed | `ogTitle`, `ogSubtitle`, `ogTheme`, `ogLogoUrl` |
| **`diff`** | Highlighted pixel-diff image of two URLs + `percentChanged` score | `url`, `compareUrl`, `diffThreshold` |
| **`decode`** | A base64 image string converted back to a downloadable file | `base64Image` |

Screenshot mode features:

- **Full page or viewport** — capture the whole scrollable page or just the fold
- **Device emulation** — iPhone 14, iPhone SE, Pixel 7, iPad Pro, desktop, or a custom viewport
- **Dark mode**, **timezone**, and **locale** emulation
- **Blocking** — strip ads, trackers, and cookie-consent banners before capture
- **Redaction** — hide or blur any CSS selector (e.g. account numbers, emails)
- **Wait strategies** — wait for a selector, network idle, or fonts + images to finish
- **DOM extraction** — return page text, links, and metadata alongside the image
- **Console capture** — collect JavaScript errors and warnings for QA / page-health checks

### Input

#### Screenshot (default mode)

Provide at least a `url` (or raw `html`). All other fields are optional:

```json
{
  "url": "https://example.com",
  "format": "png",
  "fullPage": true,
  "device": "iphone_14",
  "blockCookieBanners": true,
  "extract": ["metadata", "links"]
}
```

#### Open Graph card

```json
{
  "mode": "og",
  "ogTitle": "Ship Faster with Our API",
  "ogSubtitle": "One call. Any page. Pixel-perfect.",
  "ogTheme": "gradient"
}
```

The input above produces this card:

![Example OG card generated by this Actor](https://api.apify.com/v2/key-value-stores/Inbw2cIDCiKgO9HjC/records/og-sample.png?signature=SDVa3bjso4MfNNgGIaUm)

#### Visual diff

```json
{
  "mode": "diff",
  "url": "https://example.com",
  "compareUrl": "https://example.com/v2",
  "diffThreshold": 10
}
```

Changed pixels are highlighted, unchanged areas are greyed out
(example.com vs iana.org — 7.09% changed):

![Example visual diff generated by this Actor](https://api.apify.com/v2/key-value-stores/Inbw2cIDCiKgO9HjC/records/diff-sample.png?signature=12GQXlnnBdeQILKTgzn1W)

#### Decode base64

```json
{
  "mode": "decode",
  "base64Image": "iVBORw0KGgoAAAANSUhEUg..."
}
```

See the **Input** tab for the full, documented list of fields with defaults and bounds.

### Output

- **Key-value store** — the produced image is stored under `screenshot.<ext>`, `og-card.<ext>`,
  `diff.png`, or `decoded.<ext>` depending on the mode.
- **Dataset** — one record per run:

```json
{
  "mode": "screenshot",
  "url": "https://example.com",
  "format": "png",
  "width": 1920,
  "height": 1080,
  "captureTimeMs": 2184,
  "screenshotUrl": "https://api.apify.com/v2/key-value-stores/.../records/screenshot.png",
  "extraction": { "metadata": { "title": "Example Domain", "lang": "en" } },
  "consoleErrors": []
}
```

Diff runs additionally include `percentChanged`, `changedPixels`, and `totalPixels`.

`screenshotUrl` is a direct public link to the stored image — embed it, download it, or pass it downstream.

### Common uses

- Website thumbnails and preview images
- URL-to-PDF archiving and reporting
- Visual QA and page-health monitoring (console errors)
- Visual regression checks between two deployments or page versions
- Open Graph / social-share card generation
- Scraping page metadata and links together with a visual snapshot

***

<sub>**Operator note:** this Actor calls a dedicated Screenshot API backend. The backend base URL and
auth secret are supplied via the `SCREENSHOT_API_BASE_URL` and `SCREENSHOT_API_PROXY_SECRET`
environment variables set on the Actor — end users never need to provide them.</sub>

# Actor input Schema

## `mode` (type: `string`):

What to produce. screenshot: capture a URL or raw HTML. og: generate a 1200×630 Open Graph / social card (uses the OG fields below). diff: visually compare 'URL' against 'Compare URL' and return a highlighted diff image. decode: convert a base64 image string back to a raw image file.

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

The page to capture. Must be http(s). Mutually exclusive with 'html'.

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

Render this raw HTML instead of fetching a URL. Mutually exclusive with 'url'.

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

Image/document format to return.

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

100-3840 px. Ignored when 'device' is set.

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

100-2160 px. Ignored when 'device' is set.

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

Capture the entire scrollable page instead of just the viewport.

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

Overrides width/height/user-agent with a device emulation preset.

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

0-100. Applies to jpeg/webp only.

## `delay` (type: `integer`):

0-60. Extra wait after the page load event.

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

Wait until this element is visible before capturing.

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

load: fire on the browser load event. networkidle: load, then settle for 2s. complete: wait for fonts and images to finish too.

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

Emulate prefers-color-scheme: dark.

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

Block known ad-serving domains via CDP request blocking before capture.

## `blockTrackers` (type: `boolean`):

Block known tracker/analytics domains via CDP request blocking before capture.

## `blockCookieBanners` (type: `boolean`):

Removes common cookie-consent overlays before capture.

## `hide` (type: `string`):

Comma-separated CSS selectors to hide (display:none) before capture.

## `blur` (type: `string`):

Comma-separated CSS selectors to blur before capture (useful for redacting PII).

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

Injected as a <style> tag before capture. Max 8192 chars.

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

Overrides the browser's User-Agent header/navigator.userAgent.

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

IANA timezone, e.g. America/New\_York.

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

BCP-47 locale, e.g. fr-FR.

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

Auto-scrolls the page before capture to trigger lazy-loaded images/sections.

## `extract` (type: `array`):

Also return DOM data alongside the screenshot.

## `captureConsole` (type: `boolean`):

Also return JS console errors/warnings encountered while loading the page.

## `ogTitle` (type: `string`):

Card headline (required in og mode, max 120 chars).

## `ogSubtitle` (type: `string`):

Optional subheading under the title (max 200 chars).

## `ogLogoUrl` (type: `string`):

Optional public HTTP(S) URL of a logo shown above the title.

## `ogTheme` (type: `string`):

Card color theme.

## `ogAccentColor` (type: `string`):

Hex accent color for the title gradient, e.g. #6c63ff.

## `compareUrl` (type: `string`):

Second page to compare against 'URL' (required in diff mode).

## `diffThreshold` (type: `integer`):

Per-pixel color-distance threshold as a percentage (0-100). Pixels differing more than this count as changed. Default 10.

## `diffHighlightColor` (type: `string`):

Hex color used to mark changed pixels, e.g. #ff0000.

## `diffStabilize` (type: `boolean`):

Deterministic rendering for reliable diffs: blocks ads/trackers/cookie banners, freezes animations, waits for network idle. Recommended.

## `base64Image` (type: `string`):

Base64-encoded image — plain base64 or a data:image/...;base64,... URL. Format is sniffed from the bytes when not set explicitly via 'Output format'.

## Actor input object example

```json
{
  "mode": "screenshot",
  "url": "https://example.com",
  "format": "png",
  "width": 1920,
  "height": 1080,
  "fullPage": false,
  "device": "",
  "quality": 85,
  "delay": 2,
  "waitUntil": "load",
  "darkMode": false,
  "blockAds": false,
  "blockTrackers": false,
  "blockCookieBanners": false,
  "scrollToLoad": false,
  "captureConsole": false,
  "ogTheme": "dark",
  "diffThreshold": 10,
  "diffStabilize": true
}
```

# Actor output Schema

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

Captured images (PNG/JPEG/WebP/PDF) stored in the key-value store.

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

One record per capture with the screenshot URL and render metadata.

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

# Run the Actor and wait for it to finish
run = client.actor("moonweil/url-screenshot-api").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 moonweil/url-screenshot-api --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/4X8u4O2IIS8NiIxrM/builds/kRdf5bHHdZLiUzyEL/openapi.json
