# Website Screenshot, Fixed Price per Image (`daddyd-prints/website-screenshot-per-image`) Actor

Takes a PNG, JPEG or PDF screenshot of each web page in your list. You pay per saved screenshot. Pages that robots.txt disallows, login pages and CAPTCHA pages are skipped, listed and not charged.

- **URL**: https://apify.com/daddyd-prints/website-screenshot-per-image.md
- **Developed by:** [Derek Derringer](https://apify.com/daddyd-prints) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% 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/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, Fixed Price per Image

### What it does

This Actor saves a PNG, JPEG or PDF of each web page in your list, in desktop, tablet or phone size, at a fixed price per saved screenshot. It reads each site's robots.txt first, and every page it skips is listed with the reason and costs nothing. It never logs in, never clicks anything on a page and never tries to get past a CAPTCHA.

### How to use it

1. Open the Actor in Apify Console.
2. Paste your web addresses into **Web pages to capture**, one per line.
3. Pick the device, file format and other options. The defaults give a desktop PNG of the visible screen.
4. Click **Start**.
5. When the run ends, open the **Output** tab for the screenshot list, REPORT and SKIPPED, or the **Storage** tab for the image files.

### Input

| Field | What it does | Default | Limits |
| --- | --- | --- | --- |
| Web pages to capture (`urls`) | The pages to capture, one per line. A bare host name gets `https://` added. Duplicates are removed. | Required. Prefilled with the Apify docs home page | http and https only, up to 2000 characters, no user name or password in the address. An address with a control or invisible character, or full-width or other letter forms in its host name that a browser would turn into ordinary letters, is listed in SKIPPED as `invalid_url` and not charged |
| Device (`device`) | Screen size. Tablet and phone use 2x pixel density with touch on. | Desktop | Desktop 1280 x 800, Tablet 768 x 1024, Phone 390 x 844 |
| Full page (`fullPage`) | Captures the whole page height instead of the visible screen. | Off | The saved image is never taller than 15000 pixels: 15000 pixels of page on desktop, 7500 on tablet and phone. Not used for PDF |
| File format (`format`) | PNG, JPEG, or an A4 PDF of the page as it looks on screen. | PNG | PNG, JPEG, PDF |
| JPEG quality (`jpegQuality`) | From 1 (smallest file) to 100 (best quality). | 80 | 1 to 100, JPEG only |
| Wait after load (`waitSecs`) | Extra seconds to wait after the page has loaded and gone quiet. | 1 | 0 to 30 seconds |
| Scroll down first (`scrollBeforeCapture`) | Scrolls down and back once so images that load on scroll are shown, over the part of the page that is saved (with Full page off, one extra screen below the visible area). | Off | On or off |
| Hide cookie banners (`hideCookieBanners`) | Hides common cookie and consent banners. | On | CSS only, never clicks |
| Files from other websites (`otherSiteFiles`) | Where images, styles and scripts may load from. | Same site only (`same-site`) | `same-site` or `all` |
| Maximum screenshots (`maxScreenshots`) | How many addresses one run will process. | 100 | 1 to 5000 |
| Page timeout (`pageTimeoutSecs`) | How long one page may take to load before it is skipped. | 45 | 10 to 120 seconds |

### Output

Each saved screenshot adds one item to the run's dataset. This real item is from a local test run of the prefilled input:

```json
{
  "url": "https://docs.apify.com/",
  "finalUrl": "https://docs.apify.com/",
  "status": 200,
  "format": "png",
  "device": "desktop",
  "fullPage": false,
  "width": 1280,
  "height": 800,
  "sizeUnit": "px",
  "truncated": false,
  "pdfPages": null,
  "fileSizeBytes": 56050,
  "imageKey": "screenshot-0001-docs-apify-com.png",
  "imageUrl": "file:///.../storage/key_value_stores/default/screenshot-0001-docs-apify-com.png",
  "redirectCount": 0,
  "capturedAt": "2026-10-15T00:24:39+00:00"
}
```

The image file itself is saved in the run's default key-value store under the name in `imageKey`, numbered by its place among your accepted addresses. `imageUrl` is the Apify SDK's link to that record. In this local test it was a file link, shortened above. `width` and `height` are read from the saved file, in points for PDF, with the page count in `pdfPages`.

### Pricing

This Actor is priced per event, with two charges:

- **Actor start:** Apify's automatic start event, $0.0001 per start (one event per GB of run memory, minimum one).
- **Screenshot saved:** one charge for each screenshot saved to the dataset.

**Price per screenshot: $4.00 per 1,000 screenshots, which is $0.004 each.**

Skipped, blocked and failed pages are never charged. They are listed in the SKIPPED record with the reason. If you set a spending limit, the Actor checks before each page that another screenshot still fits. When none does, the run stops cleanly, lists the rest in SKIPPED as `spending_limit_reached` and writes REPORT.

### What it will not do

- **Skip robots.txt.** It is read for every site before any other request to that site, redirects and page files included, and cannot be switched off. The group for `website-screenshot-per-image` applies, otherwise the `*` group.
- **Fetch disallowed pages.** They are skipped, listed in SKIPPED with the matching rule, and not charged. A `Disallow: /` for this Actor skips the whole site even when Allow lines exist, and so does a robots.txt that answers with a server error, 401, 403 or 429, or cannot be reached.
- **Get past a login or CAPTCHA.** It stops at login pages, 401, 403 and 429 answers and CAPTCHA or bot check pages, and never tries to get past them. Any visible password field counts as a login page, so a page with a login box in its header is skipped.
- **Click anything.** Cookie banners are hidden with CSS only, so a banner it does not recognise stays in the picture.
- **Hide what it is.** There is no cookie, header, login, proxy or user agent input. The user agent is the browser's own plus `website-screenshot-per-image/0.1`, so a site that picks its layout from the user agent alone may show its desktop layout in phone and tablet captures.
- **Crowd a site.** One request at a time goes to each site, and a robots.txt Crawl-delay is honoured between requests, page files included. Such pages load slowly and may time out, which is not charged. A Crawl-delay over 30 seconds skips the site.
- **Load video, audio or private addresses.** Video and audio are not loaded, and addresses on private or local networks are skipped.

### Your responsibility

You are responsible for having the right to capture each page you list and for following each website's terms of use. The Actor checks robots.txt for you, but it cannot read or judge a site's terms.

### Run records

The run's key-value store also holds three records:

- **REPORT:** start and finish times, why the run stopped, the settings used, any input problems, counts with skips by reason, and the robots.txt result and requests for each site.
- **SKIPPED:** every address not captured, with the reason, a detail, and the HTTP status and final address where known. None of them is charged.
- **STATE:** a resume marker holding the next position in your list and the saved and charged counts. If Apify moves the run to another server part way through, the run continues from there without retaking or recharging a saved screenshot.

### Limits

- **Addresses:** up to 5000 per run, 100 by default. Addresses past your Maximum screenshots are listed in SKIPPED as `over_max_screenshots` and not charged.
- **Page height:** a full page image is never taller than 15000 pixels, which is 15000 pixels of page on desktop and 7500 on tablet and phone. A cut image shows `truncated: true`.
- **Timeouts:** 10 to 120 seconds per page, 45 by default. Each single request is also capped at 30 seconds and 30 MB.
- **Files from other websites:** `same-site`, the default, loads images, styles and scripts only from the page's own website and its subdomains, so images or fonts served from another domain are missing. `all` loads them too, after a robots.txt check for each site.
- **Downloads:** an address that starts a file download is skipped.

# Actor input Schema

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

One web address per line, starting with http:// or https://. An address without one gets https:// added. Duplicates are removed. An address holding a control character or an invisible character (such as a zero-width space), or full-width or other letter forms in its host name that a browser would turn into ordinary letters, is listed in SKIPPED as invalid and not charged. Before anything is requested from a site, the Actor reads that site's robots.txt, and any page it disallows is skipped, listed in the SKIPPED record and not charged.

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

Screen size used for the capture. Desktop is 1280 x 800. Tablet is 768 x 1024 and phone is 390 x 844, both at 2x pixel density with touch turned on. The browser always identifies itself honestly, so a site that chooses its layout from the user agent alone may still show its desktop layout.

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

Capture the whole page height instead of only the visible screen. The saved image is never taller than 15000 pixels: a longer page is cut there and marked truncated. Tablet and phone save 2 image pixels for every page pixel, so on those devices the cut comes after the first 7500 pixels of page height. Not used for PDF.

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

PNG gives sharp text. JPEG gives smaller files. PDF saves an A4 PDF of the page as it looks on screen.

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

Only used for JPEG. From 1 (smallest file) to 100 (best quality).

## `waitSecs` (type: `integer`):

Extra seconds to wait after the page has loaded and gone quiet, before the capture. Useful for pages that animate in. Longer waits make runs longer.

## `scrollBeforeCapture` (type: `boolean`):

Scrolls down once before the capture and then back to the top, so images that load only when scrolled into view are shown. It scrolls only over the part that can be saved. With Full page on, the bottom of the screen goes down to where the capture is cut: 15000 pixels of page on desktop, 7500 on tablet and phone. With Full page off, it goes one extra screen height below the visible screen. For PDF it goes down to 15000 pixels of page.

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

Hides common cookie and consent banners with CSS. The Actor never clicks any button on a page, including accept or consent buttons, so a banner it does not recognise stays visible.

## `otherSiteFiles` (type: `string`):

Same site loads images, styles and scripts only from the page's own website and its subdomains, which also leaves out most ads, trackers and third party consent pop ups. All websites also loads files from other websites. Either way, every website is checked against its own robots.txt before the browser requests anything from it.

## `maxScreenshots` (type: `integer`):

The most screenshots this run will take. Addresses beyond this number are listed in SKIPPED and not charged. Your spending limit for the run is also respected.

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

How long one page may take to load before it is skipped. A skipped page is not charged.

## Actor input object example

```json
{
  "urls": [
    "https://docs.apify.com"
  ],
  "device": "desktop",
  "fullPage": false,
  "format": "png",
  "jpegQuality": 80,
  "waitSecs": 1,
  "scrollBeforeCapture": false,
  "hideCookieBanners": true,
  "otherSiteFiles": "same-site",
  "maxScreenshots": 100,
  "pageTimeoutSecs": 45
}
```

# Actor output Schema

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

No description

## `report` (type: `string`):

No description

## `skipped` (type: `string`):

No description

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

// Run the Actor and wait for it to finish
const run = await client.actor("daddyd-prints/website-screenshot-per-image").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://docs.apify.com"] }

# Run the Actor and wait for it to finish
run = client.actor("daddyd-prints/website-screenshot-per-image").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://docs.apify.com"
  ]
}' |
apify call daddyd-prints/website-screenshot-per-image --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,daddyd-prints/website-screenshot-per-image"
        }
    }
}
```

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/kb2Untue0jmXN3Kyi/builds/bkDMjVf6ery7S5wRf/openapi.json
