# Website Screenshot — bulk full-page captures, multi-device (`titian_troupe/screenshot`) Actor

Capture full-page or viewport screenshots of any list of URLs. Desktop, laptop, tablet and mobile presets or a custom viewport, PNG or JPEG, dark mode, with cookie banners hidden and ad/tracker requests blocked so captures are clean and repeatable.

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

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## 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 — bulk full-page captures, multi-device

Screenshot any list of URLs. Full-page or viewport, four device presets or a custom size,
PNG or JPEG — with **cookie banners hidden and ad/tracker requests blocked** so captures are
clean and repeatable rather than a wall of consent dialogs.

### Why captures come out clean

Three things run on every page before the shutter:

1. **Consent dialogs are hidden.** CSS targets the common offenders — OneTrust, Cookiebot,
   and anything matching cookie/consent/GDPR id, class or aria-label patterns.
2. **Animations are frozen.** Transition and animation durations are forced to zero, so you
   do not capture a half-finished slide-in. This also makes repeat captures diffable.
3. **Ads and trackers are aborted.** DoubleClick, Google Syndication, Amazon adsystem,
   Taboola, Outbrain, GA, GTM, Hotjar, Segment, Mixpanel, FullStory. Faster loads, and no
   layout shift from a late-loading ad slot.

Each can be turned off individually.

### Input

```json
{
  "urls": ["https://example.com", "example.com/pricing"],
  "device": "desktop",
  "fullPage": true,
  "format": "png",
  "hideCookieBanners": true,
  "blockAds": true,
  "darkMode": false
}
```

| Field | Default | Notes |
|---|---|---|
| `urls` | — | Required. Bare domains accepted. |
| `device` | `desktop` | `desktop` 1920×1080, `laptop` 1366×768, `tablet` 768×1024 @2x, `mobile` 390×844 @3x |
| `viewportWidth` / `viewportHeight` | — | Override the preset size |
| `fullPage` | `true` | Capture the whole document height, not just the viewport |
| `format` | `png` | `png` (lossless) or `jpeg` (smaller, takes `quality`) |
| `quality` | 80 | JPEG only |
| `waitUntil` | `networkidle` | `load`, `domcontentloaded`, `networkidle`, `commit` |
| `waitExtraMs` | 500 | Extra pause for late animations or lazy images |
| `timeoutMs` | 45000 | Per-URL navigation timeout |
| `darkMode` | `false` | Emulate `prefers-color-scheme: dark` |

### Output

Images go to the run's key-value store. Each dataset item carries a **direct URL** to its
image, so you can pipe results straight into a report or a sheet:

```json
{
  "url": "https://example.com/",
  "ok": true,
  "statusCode": 200,
  "title": "Example Domain",
  "device": "desktop",
  "viewportWidth": 1920,
  "viewportHeight": 1080,
  "fullPage": true,
  "format": "png",
  "bytes": 19955,
  "screenshotKey": "0000-example-com-desktop-full.png",
  "screenshotUrl": "https://api.apify.com/v2/key-value-stores/<id>/records/0000-example-com-desktop-full.png",
  "loadTimeMs": 2460
}
```

Keys are **deterministic** — same URL, device and mode produce the same key — so re-runs
overwrite rather than piling up near-duplicates. They are prefixed with a zero-padded index
so the store sorts in input order.

Failed URLs are still recorded, with `ok: false` and a `reason`, so nothing disappears
silently from a batch.

### Typical uses

- **Visual regression** — schedule daily; deterministic keys make captures directly comparable
- **Responsive QA** — run the same URLs at all four device presets
- **Competitor tracking** — weekly captures of competitor pricing and landing pages
- **Client reporting** — full-page shots of every page you touched, with direct image links
- **Design and pitch decks** — bulk-capture reference sites in one pass

### Limits

Pages behind a login are not supported — there is no credential input. Sites with aggressive
bot protection may serve a challenge page; that is captured faithfully as what an anonymous
visitor sees. Very long pages (tens of thousands of pixels) can exceed browser capture
limits, in which case set `fullPage: false` and a tall custom viewport.

# Actor input Schema

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

Pages to capture. A bare domain is accepted and https:// is assumed. Wire this to a crawler Actor to screenshot a whole site.

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

Sets viewport size, pixel density and touch emulation. Override the size with the two fields below if you need something specific.

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

Overrides the preset width. Leave empty to use the device preset.

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

Overrides the preset height. Ignored when Full page is on, except as the initial window size.

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

Scroll and capture the entire document height rather than just the visible viewport.

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

PNG is lossless and larger. JPEG is smaller and takes a quality setting.

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

1-100. Only applies when the format is JPEG.

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

How long to wait before capturing. 'networkidle' gives the most complete render; 'load' is faster on heavy pages that never go idle.

## `waitExtraMs` (type: `integer`):

Additional pause after the wait condition, for late animations or lazy-loaded images.

## `timeoutMs` (type: `integer`):

Per-URL navigation timeout. Pages exceeding it are recorded as failed rather than stalling the run.

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

Inject CSS that hides common consent dialogs (OneTrust, Cookiebot and similar) and disables animations, so captures are clean and repeatable.

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

Abort requests to common ad networks. Speeds up capture and removes layout shift.

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

Abort requests to analytics and session-recording providers.

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

Emulate prefers-color-scheme: dark.

## Actor input object example

```json
{
  "urls": [
    "https://apify.com",
    "example.com"
  ],
  "device": "desktop",
  "fullPage": true,
  "format": "png",
  "quality": 80,
  "waitUntil": "networkidle",
  "waitExtraMs": 500,
  "timeoutMs": 45000,
  "hideCookieBanners": true,
  "blockAds": true,
  "blockTrackers": true,
  "darkMode": 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 = {
    "urls": [
        "https://apify.com",
        "example.com"
    ]
};

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

# Run the Actor and wait for it to finish
run = client.actor("titian_troupe/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 '{
  "urls": [
    "https://apify.com",
    "example.com"
  ]
}' |
apify call titian_troupe/screenshot --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/XZ4qpkjM8HOvecC0S/builds/ZP4vqeY8h3RLABvWQ/openapi.json
