# Ultimate Website Screenshot / PDF / Video (`crawlerbros/ultimate-screenshot`) Actor

Capture JPEG/PNG screenshots, PDFs, GIFs and MP4s of any website. 12+ device presets, full-page, custom viewport, scroll-to-bottom, cookie injection, proxy support.

- **URL**: https://apify.com/crawlerbros/ultimate-screenshot.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Developer tools, Automation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 8 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## Ultimate Website Screenshot, PDF, GIF and Video Capture

Capture any web page as a pixel-perfect **JPEG**, **PNG**, **PDF document**, animated **GIF**, or **MP4 video** — all from a single Apify actor, with 31 real device presets out of the box.

### What this actor does

Feed this actor one or more URLs and it loads each page in a real browser at the device and viewport you choose, then produces the capture in the format you need. Assets are stored in the run's key-value store and referenced in the dataset via a direct download link — ready to embed in reports, pipe into a CDN, or attach to a ticket.

It supports full-page captures that stitch the entire scrollable height (for images and PDFs), animated captures that scroll the page across frames (for GIF/MP4), and **31 device presets** covering everything from a 4K desktop monitor to an iPhone 15 Pro Max and a foldable Surface Duo. A custom viewport is also available if none of the presets match. Anti-bot resilience is built in: when a target page responds with a block/challenge page, the actor's **auto proxy fallback** detects it and silently retries the capture through a residential proxy session, so you get a real screenshot instead of a CAPTCHA image.

Everything is configurable — JPEG quality, PDF paper size and margins, navigation wait strategy, post-load delay, scroll-to-bottom behavior, cookie injection for session-walled pages, and MP4/GIF frame timing. The result is one consistent tool that replaces half a dozen specialized screenshot services.

### Key features

- **Five output formats** — JPEG, PNG, PDF, GIF, MP4.
- **31 device presets** — desktop monitors (1080p, 1440p, 4K), MacBook Pro 14/16, iPhone 13/14/15 families, Pixel phones, Galaxy phones, iPad Pro/Mini, Surface Duo, plus a Custom viewport option.
- **Full-page capture** that stitches the entire scrollable height for images and PDFs.
- **Animated captures** — GIF and MP4 with configurable frame count, interval, FPS, and scroll step per frame.
- **Scroll-to-bottom trigger** to force lazy-loaded images and content to render before capture.
- **Auto proxy fallback** — detects block/challenge pages and silently retries through a residential proxy so the run still produces a usable asset.
- **Cookie injection** for pages behind simple session walls.
- **Proxy support** (Apify Proxy or custom proxy URLs) for geo-specific or blocked pages.
- **Configurable waits** — `load`, `domcontentloaded`, or `networkidle`, plus a user-defined delay.
- **PDF controls** — A4 / Letter / Legal paper size, millimeter margins, background printing toggle.
- **Graceful degradation** — if MP4 encoding fails at runtime the actor falls back to a JPEG of the target page so your dataset is never empty.

### Input

| Field | Description |
|---|---|
| `linkUrls` | One or more `http`/`https` URLs to capture. |
| `outputFormat` | `jpeg`, `png`, `pdf`, `gif`, or `mp4`. |
| `device` | Any of the 31 presets, or `Custom` to use your own viewport. |
| `windowWidth` / `windowHeight` | Viewport size when `device` is `Custom`. |
| `fullPage` | Capture the entire scrollable page (applies to images + PDF). |
| `waitUntil` | Navigation wait strategy: `load`, `domcontentloaded`, or `networkidle`. |
| `timeoutSeconds` | Navigation timeout in seconds (1–120). |
| `delayBeforeScreenshotMs` | Extra wait after page load, in milliseconds (0–30000). |
| `scrollToBottom` | Scroll the page before capture to trigger lazy content. |
| `jpegQuality` | JPEG quality (1–100). |
| `pdfFormat` / `pdfPrintBackground` / `pdfMargin*` | Paper size, background toggle, margins (mm). |
| `videoFrameCount`, `videoFrameIntervalMs`, `videoFps`, `videoScrollStepPx` | Control GIF/MP4 length, timing, and scroll-per-frame. |
| `cookies` | Array of `{name, value, domain?}` cookies injected into the browser. |
| `enableSSL` | When `false` (default), invalid HTTPS certificates are ignored. |
| `autoProxyFallback` | When true (default), detect block/challenge pages and retry via residential proxy. |
| `proxyConfiguration` | Apify Proxy or custom proxy URLs. |

**Example input**

```json
{
  "linkUrls": [
    { "url": "https://news.ycombinator.com" },
    { "url": "https://example.com/pricing" }
  ],
  "outputFormat": "png",
  "device": "Desktop 1920x1080",
  "fullPage": true,
  "scrollToBottom": true,
  "waitUntil": "networkidle",
  "delayBeforeScreenshotMs": 1500,
  "autoProxyFallback": true
}
````

### Output

Each capture produces one dataset record:

```json
{
  "linkUrl": "https://example.com/pricing",
  "screenshotUrl": "https://api.apify.com/v2/key-value-stores/.../records/example-pricing.png",
  "storageKey": "example-pricing.png",
  "contentType": "image/png",
  "fileSizeBytes": 428913,
  "device": "Desktop 1920x1080",
  "viewportWidth": 1920,
  "viewportHeight": 1080,
  "format": "png",
  "capturedAtUTC": "2026-04-24T10:15:00+00:00"
}
```

**Field descriptions**

- `linkUrl` — the URL that was captured.
- `screenshotUrl` — direct download link to the captured asset in the run's key-value store.
- `storageKey` — key inside the run's key-value store (useful when referencing assets by convention).
- `contentType` — MIME type of the asset (`image/jpeg`, `image/png`, `application/pdf`, `image/gif`, `video/mp4`).
- `fileSizeBytes` — size of the stored asset in bytes.
- `device` — the device preset used (or `Custom`).
- `viewportWidth` / `viewportHeight` — actual viewport dimensions used for the capture.
- `format` — final format saved. May differ from the requested format if the MP4 fallback engaged.
- `capturedAtUTC` — ISO 8601 UTC timestamp of capture.

If a URL cannot be captured at all, a compact error record is written in its place with `type: screenshot_error` and a human-readable `message`, so your dataset is never silently empty.

### Use cases

- **Automated QA & visual regression** — screenshot every critical page in your marketing site across desktop + mobile presets on every deploy.
- **Archiving & compliance** — snapshot competitor pricing pages, regulated content, or legal notices as dated PDFs for record keeping.
- **Social media & preview cards** — generate high-DPI screenshots of pages to embed in blog posts, Slack threads, and Notion docs.
- **Marketing demos** — record short MP4/GIF walkthroughs of a web app scrolling through its home page for pitch decks and ads.
- **Accessibility & cross-device review** — compare how the same page renders across iPhone 15 Pro Max, Pixel 8, and a 4K desktop without owning the hardware.

### FAQ

**Can it capture sites that block bots?**
Yes in most cases. The actor uses a real browser with a realistic user agent and respects the `waitUntil` and `delayBeforeScreenshotMs` settings so content renders before capture. When a target page responds with a block/challenge page, `autoProxyFallback` (on by default) retries the capture through a residential proxy session automatically.

**How do I capture pages behind a login?**
Paste your session cookies as an array of `{name, value, domain?}` objects into the `cookies` field. If `domain` is omitted, the page's host is used.

**Does full-page capture work for every format?**
Full-page applies to image (JPEG/PNG) and PDF formats. GIF and MP4 capture the current viewport across a sequence of frames while scrolling, so they reflect real on-screen animation.

**What if MP4 encoding fails at runtime?**
The actor falls back to a JPEG of the target page and marks `format: "jpeg"` in the dataset record so your run still produces usable output rather than an error.

**What's the difference between `load`, `domcontentloaded`, and `networkidle`?**
`domcontentloaded` is fastest (fires once the HTML is parsed), `load` waits for images and subresources, and `networkidle` waits until there are no network requests for 500ms — best for JS-heavy apps but slowest.

**Will it capture every pixel of an infinite-scroll page?**
No tool can — infinite scroll has no end. Use `scrollToBottom` to trigger lazy-loading and set a reasonable page height cap via `videoFrameCount` (for MP4/GIF) to control how far the capture scrolls.

**Do I pay per screenshot?**
Pricing is set in the Apify UI, separate from the actor itself. Costs depend on run duration, compute, and whether you use residential proxy.

### Known limitations

- **Infinite-scroll feeds** (Twitter, TikTok) cannot be fully captured — full-page stitches only the currently-loaded DOM, not content that requires scrolling to materialize indefinitely.
- **DRM-protected video** (Netflix, DRM-locked streaming) cannot be recorded in MP4 captures — the browser blacks out protected frames.
- **CAPTCHA gates** that block all browser traffic (including real users) cannot be bypassed; those pages will be captured as-is or emit an error record.
- **Fixed-position headers/footers** can appear duplicated in full-page stitched screenshots on some sites — this is a common browser rendering limitation across all screenshot tools.
- **Large MP4 captures** (high frame count at high resolution) produce large files. Use reasonable `videoFrameCount` and `videoFps` values to keep storage manageable.

# Actor input Schema

## `linkUrls` (type: `array`):

List of page URLs to capture as screenshot / PDF / GIF / MP4.

## `outputFormat` (type: `string`):

Choose capture format.

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

Capture the entire scrollable page (images/PDF only).

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

Playwright navigation waitUntil condition.

## `timeoutSeconds` (type: `integer`):

Maximum seconds to wait for page navigation.

## `delayBeforeScreenshotMs` (type: `integer`):

Extra wait after load before capturing, in milliseconds.

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

Pick a device preset to emulate, or Custom to use the windowWidth / windowHeight fields.

## `windowWidth` (type: `integer`):

Viewport width in pixels (used only when Device = Custom).

## `windowHeight` (type: `integer`):

Viewport height in pixels (used only when Device = Custom).

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

Scroll to page bottom before capture to trigger lazy-loaded content.

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

JPEG compression quality 1-100.

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

Paper size for PDF output.

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

Render CSS backgrounds and colors in the PDF.

## `pdfMarginTop` (type: `integer`):

Top margin of the PDF in millimeters.

## `pdfMarginRight` (type: `integer`):

Right margin of the PDF in millimeters.

## `pdfMarginBottom` (type: `integer`):

Bottom margin of the PDF in millimeters.

## `pdfMarginLeft` (type: `integer`):

Left margin of the PDF in millimeters.

## `videoFrameCount` (type: `integer`):

Number of frames to capture for GIF/MP4 output.

## `videoFrameIntervalMs` (type: `integer`):

Milliseconds to wait between frames.

## `videoFps` (type: `integer`):

Playback frames per second for the rendered GIF/MP4.

## `videoScrollStepPx` (type: `integer`):

Pixels to scroll down between consecutive frames.

## `cookies` (type: `array`):

Optional list of cookies to inject. Each entry: {name, value, domain?}. Domain derives from URL if omitted.

## `enableSSL` (type: `boolean`):

If false (default), ignore HTTPS certificate errors.

## `autoProxyFallback` (type: `boolean`):

When the primary capture returns a suspiciously small file (e.g. an Akamai/Cloudflare block page on banks, airlines, Amazon product pages), automatically retry that URL once via Apify residential proxy. Only blocked URLs burn proxy credits. Turn off to guarantee zero proxy spend.

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

Force every capture through this proxy. Prefer `autoProxyFallback` — it only uses proxy on blocked pages.

## Actor input object example

```json
{
  "linkUrls": [
    "https://apify.com"
  ],
  "outputFormat": "jpeg",
  "fullPage": false,
  "waitUntil": "networkidle",
  "timeoutSeconds": 30,
  "delayBeforeScreenshotMs": 1500,
  "device": "Desktop 1920x1080",
  "windowWidth": 1920,
  "windowHeight": 1080,
  "scrollToBottom": false,
  "jpegQuality": 85,
  "pdfFormat": "A4",
  "pdfPrintBackground": true,
  "pdfMarginTop": 10,
  "pdfMarginRight": 10,
  "pdfMarginBottom": 10,
  "pdfMarginLeft": 10,
  "videoFrameCount": 30,
  "videoFrameIntervalMs": 200,
  "videoFps": 10,
  "videoScrollStepPx": 400,
  "cookies": [],
  "enableSSL": false,
  "autoProxyFallback": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# 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 = {
    "linkUrls": [
        "https://apify.com"
    ],
    "outputFormat": "jpeg",
    "device": "Desktop 1920x1080"
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/ultimate-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 = {
    "linkUrls": ["https://apify.com"],
    "outputFormat": "jpeg",
    "device": "Desktop 1920x1080",
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/ultimate-screenshot").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 '{
  "linkUrls": [
    "https://apify.com"
  ],
  "outputFormat": "jpeg",
  "device": "Desktop 1920x1080"
}' |
apify call crawlerbros/ultimate-screenshot --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Ultimate Website Screenshot / PDF / Video",
        "description": "Capture JPEG/PNG screenshots, PDFs, GIFs and MP4s of any website. 12+ device presets, full-page, custom viewport, scroll-to-bottom, cookie injection, proxy support.",
        "version": "0.1",
        "x-build-id": "dEzu93TMUWbJj87Hk"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/crawlerbros~ultimate-screenshot/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-crawlerbros-ultimate-screenshot",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/crawlerbros~ultimate-screenshot/runs": {
            "post": {
                "operationId": "runs-sync-crawlerbros-ultimate-screenshot",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/crawlerbros~ultimate-screenshot/run-sync": {
            "post": {
                "operationId": "run-sync-crawlerbros-ultimate-screenshot",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "linkUrls"
                ],
                "properties": {
                    "linkUrls": {
                        "title": "URLs to Capture",
                        "type": "array",
                        "description": "List of page URLs to capture as screenshot / PDF / GIF / MP4.",
                        "default": [
                            "https://apify.com"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "outputFormat": {
                        "title": "Output Format",
                        "enum": [
                            "jpeg",
                            "png",
                            "pdf",
                            "gif",
                            "mp4"
                        ],
                        "type": "string",
                        "description": "Choose capture format.",
                        "default": "jpeg"
                    },
                    "fullPage": {
                        "title": "Full Page",
                        "type": "boolean",
                        "description": "Capture the entire scrollable page (images/PDF only).",
                        "default": false
                    },
                    "waitUntil": {
                        "title": "Wait Until",
                        "enum": [
                            "load",
                            "domcontentloaded",
                            "networkidle"
                        ],
                        "type": "string",
                        "description": "Playwright navigation waitUntil condition.",
                        "default": "networkidle"
                    },
                    "timeoutSeconds": {
                        "title": "Navigation Timeout (seconds)",
                        "minimum": 1,
                        "maximum": 120,
                        "type": "integer",
                        "description": "Maximum seconds to wait for page navigation.",
                        "default": 30
                    },
                    "delayBeforeScreenshotMs": {
                        "title": "Delay Before Capture (ms)",
                        "minimum": 0,
                        "maximum": 30000,
                        "type": "integer",
                        "description": "Extra wait after load before capturing, in milliseconds.",
                        "default": 1500
                    },
                    "device": {
                        "title": "Device Preset",
                        "enum": [
                            "Desktop 1920x1080",
                            "Desktop 2560x1440",
                            "Desktop 1440x900",
                            "Laptop 1366x768",
                            "MacBook Pro 14",
                            "MacBook Pro 16",
                            "iMac 27",
                            "iPhone SE",
                            "iPhone 12",
                            "iPhone 13",
                            "iPhone 14",
                            "iPhone 14 Pro Max",
                            "iPhone 15",
                            "iPhone 15 Pro",
                            "iPhone 15 Pro Max",
                            "iPad Mini",
                            "iPad Air",
                            "iPad 10.2",
                            "iPad Pro",
                            "Pixel 5",
                            "Pixel 7",
                            "Pixel 8",
                            "Pixel 8 Pro",
                            "Galaxy S22",
                            "Galaxy S23",
                            "Galaxy S24",
                            "Galaxy S24 Ultra",
                            "Galaxy Z Fold 5",
                            "OnePlus 11",
                            "Surface Duo 2",
                            "Custom"
                        ],
                        "type": "string",
                        "description": "Pick a device preset to emulate, or Custom to use the windowWidth / windowHeight fields.",
                        "default": "Desktop 1920x1080"
                    },
                    "windowWidth": {
                        "title": "Window Width (Custom device)",
                        "minimum": 200,
                        "maximum": 3840,
                        "type": "integer",
                        "description": "Viewport width in pixels (used only when Device = Custom).",
                        "default": 1920
                    },
                    "windowHeight": {
                        "title": "Window Height (Custom device)",
                        "minimum": 200,
                        "maximum": 2400,
                        "type": "integer",
                        "description": "Viewport height in pixels (used only when Device = Custom).",
                        "default": 1080
                    },
                    "scrollToBottom": {
                        "title": "Scroll To Bottom First",
                        "type": "boolean",
                        "description": "Scroll to page bottom before capture to trigger lazy-loaded content.",
                        "default": false
                    },
                    "jpegQuality": {
                        "title": "JPEG Quality",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "JPEG compression quality 1-100.",
                        "default": 85
                    },
                    "pdfFormat": {
                        "title": "PDF Paper Size",
                        "enum": [
                            "A4",
                            "Letter",
                            "Legal"
                        ],
                        "type": "string",
                        "description": "Paper size for PDF output.",
                        "default": "A4"
                    },
                    "pdfPrintBackground": {
                        "title": "PDF: Print Backgrounds",
                        "type": "boolean",
                        "description": "Render CSS backgrounds and colors in the PDF.",
                        "default": true
                    },
                    "pdfMarginTop": {
                        "title": "PDF Margin Top (mm)",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Top margin of the PDF in millimeters.",
                        "default": 10
                    },
                    "pdfMarginRight": {
                        "title": "PDF Margin Right (mm)",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Right margin of the PDF in millimeters.",
                        "default": 10
                    },
                    "pdfMarginBottom": {
                        "title": "PDF Margin Bottom (mm)",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Bottom margin of the PDF in millimeters.",
                        "default": 10
                    },
                    "pdfMarginLeft": {
                        "title": "PDF Margin Left (mm)",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Left margin of the PDF in millimeters.",
                        "default": 10
                    },
                    "videoFrameCount": {
                        "title": "Video/GIF Frame Count",
                        "minimum": 5,
                        "maximum": 120,
                        "type": "integer",
                        "description": "Number of frames to capture for GIF/MP4 output.",
                        "default": 30
                    },
                    "videoFrameIntervalMs": {
                        "title": "Frame Interval (ms)",
                        "minimum": 50,
                        "maximum": 2000,
                        "type": "integer",
                        "description": "Milliseconds to wait between frames.",
                        "default": 200
                    },
                    "videoFps": {
                        "title": "Output FPS",
                        "minimum": 5,
                        "maximum": 60,
                        "type": "integer",
                        "description": "Playback frames per second for the rendered GIF/MP4.",
                        "default": 10
                    },
                    "videoScrollStepPx": {
                        "title": "Scroll Step (px per frame)",
                        "minimum": 0,
                        "maximum": 2000,
                        "type": "integer",
                        "description": "Pixels to scroll down between consecutive frames.",
                        "default": 400
                    },
                    "cookies": {
                        "title": "Cookies",
                        "type": "array",
                        "description": "Optional list of cookies to inject. Each entry: {name, value, domain?}. Domain derives from URL if omitted.",
                        "default": []
                    },
                    "enableSSL": {
                        "title": "Enforce SSL",
                        "type": "boolean",
                        "description": "If false (default), ignore HTTPS certificate errors.",
                        "default": false
                    },
                    "autoProxyFallback": {
                        "title": "Auto-retry blocked captures via proxy",
                        "type": "boolean",
                        "description": "When the primary capture returns a suspiciously small file (e.g. an Akamai/Cloudflare block page on banks, airlines, Amazon product pages), automatically retry that URL once via Apify residential proxy. Only blocked URLs burn proxy credits. Turn off to guarantee zero proxy spend.",
                        "default": true
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration (use for ALL captures)",
                        "type": "object",
                        "description": "Force every capture through this proxy. Prefer `autoProxyFallback` — it only uses proxy on blocked pages.",
                        "default": {
                            "useApifyProxy": false
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
