# Website Screenshot (PNG, JPEG, PDF) (`ttechx/website-screenshot`) Actor

Take full-page or viewport screenshots of any website as PNG, JPEG or PDF. Hides ads and cookie banners, supports custom viewport, retina, dark mode, element capture and bulk URLs.

- **URL**: https://apify.com/ttechx/website-screenshot.md
- **Developed by:** [TTech](https://apify.com/ttechx) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 screenshots

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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 — PNG, JPEG & PDF

Take clean screenshots of any website as **PNG**, **JPEG/JPG** or **PDF**. Paste one URL or thousands, and get back image files ready to download, embed or send to other tools.

### What can it do?

- 📸 **Viewport or full-page** screenshots, with a height limit for very long pages
- 🖼️ **PNG, JPEG/JPG or PDF** output, with adjustable JPEG quality and PDF page size
- 🚫 **Hides ads and cookie banners** automatically for a clean image
- 🔍 **Retina / HiDPI** images (2× or 3× scale)
- 🌙 **Dark mode**: asks sites to use their dark theme
- 🎯 **Capture one element** using a CSS selector, e.g. a pricing table or a chart
- ⏳ **Waits for JavaScript-heavy sites**: network idle, wait for an element, or a fixed delay
- 🖱️ **Loads lazy images** by scrolling the page before a full-page capture
- 🧩 **Custom CSS & JavaScript**, extra headers, cookies and user agent
- 🌍 **Proxy support** for geo-specific content and sites that block data centers
- ⚡ **Bulk**: captures many URLs in parallel

### How to use it

1. Add one or more URLs.
2. Pick the output format and any options.
3. Click **Start**. When the run finishes, open the **Output** tab to preview and download each file.

#### Example input

```json
{
    "urls": [{ "url": "https://apify.com" }, { "url": "https://en.wikipedia.org/wiki/Web_scraping" }],
    "format": "png",
    "fullPage": true,
    "width": 1440,
    "height": 900,
    "scaleFactor": 2,
    "hideAds": true,
    "hideCookieBanners": true
}
```

#### Example output

Each URL produces one item in the dataset. The file itself lives in the run's key-value store, and `fileUrl` is a direct download link.

```json
{
    "url": "https://apify.com/",
    "status": "success",
    "format": "png",
    "screenshotUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/apify-com-1a2b3c4d.png",
    "fileUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/apify-com-1a2b3c4d.png",
    "fileKey": "apify-com-1a2b3c4d.png",
    "contentType": "image/png",
    "sizeBytes": 845123,
    "httpStatus": 200,
    "finalUrl": "https://apify.com/",
    "title": "Apify: Full-stack web scraping and data extraction platform",
    "width": 1440,
    "height": 900,
    "fullPage": true,
    "pageHeight": 7340,
    "truncated": false,
    "takenAt": "2026-10-17T10:00:00.000Z"
}
```

If a page can't be captured (timeout, DNS error, invalid URL), the item has `"status": "failed"` and an `error` message. **You are not charged for failed screenshots.**

### Use it from your code

Run the actor and get the results in one HTTP call. Find your API token in [Apify Console → Settings → API & Integrations](https://console.apify.com/settings/integrations).

```bash
curl -X POST "https://api.apify.com/v2/acts/ttechx~website-screenshot/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"urls": [{"url": "https://example.com"}], "format": "jpeg", "quality": 80}'
```

Or with the JavaScript client:

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('ttechx/website-screenshot').call({
    urls: [{ url: 'https://example.com' }],
    format: 'png',
    fullPage: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((item) => item.fileUrl));
```

### ⚡ Instant screenshot API (Standby mode)

Need a screenshot back in a couple of seconds, like a classic screenshot API? Call the Actor's Standby endpoint. It keeps a warm browser ready, so there is no start-up wait: most pages come back in **1–4 seconds**, and the response body is the image itself.

```bash
curl "https://ttechx--website-screenshot.apify.actor/?url=https://example.com&format=png&full_page=true" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>" -o screenshot.png
```

You can paste the URL straight into an `<img>` tag or any HTTP client. Parameters use the same names as the input (snake_case or camelCase), and common names from other screenshot APIs also work:

| Parameter                     | Example                                     | Notes                                                                                                                             |
| ----------------------------- | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `url`                         | `https://example.com`                       | Required                                                                                                                          |
| `format`                      | `jpeg`, `png`, `jpg`, `pdf`                 | Default `jpeg` (smallest, so fastest to download)                                                                                 |
| `width`, `height`             | `1280`, `800`                               | Viewport size                                                                                                                     |
| `full_page`                   | `true`                                      | Whole page instead of the viewport                                                                                                |
| `quality`                     | `80`                                        | JPEG only                                                                                                                         |
| `scale_factor`                | `2`                                         | Retina                                                                                                                            |
| `wait_until`                  | `dom_loaded`, `page_loaded`, `network_idle` | Default `page_loaded`                                                                                                             |
| `delay`                       | `2`                                         | Extra seconds to wait                                                                                                             |
| `wait_for` / `element`        | `.chart`                                    | Wait for / capture one element                                                                                                    |
| `no_ads`, `no_cookie_banners` | `false`                                     | Both on by default                                                                                                                |
| `hide_selectors`              | `.popup,#chat`                              | Comma-separated                                                                                                                   |
| `dark_mode`                   | `true`                                      |                                                                                                                                   |
| `proxy`                       | `datacenter`, `residential`                 | Default: no proxy (fastest)                                                                                                       |
| `response_type`               | `redirect`, `json`                          | `redirect` sends you to a fast download link (best for full-page and other big images); `json` returns the link with page details |

**Tip for big images:** add `response_type=redirect` (and use `curl -L`). Large files then download straight from Apify storage instead of streaming through the API, which is often faster for clients far from the US. Links stay valid for as long as Apify keeps the run's storage (7 days by default).

Pricing is the same per screenshot/PDF. In Standby mode, Apify bills the platform usage of the warm browser to your account in addition.

### Pricing

You pay per successful capture:

| Event                                             | Price                                     | Per 1,000  |
| ------------------------------------------------- | ----------------------------------------- | ---------- |
| Screenshot (PNG / JPEG / JPG)                     | $0.002                                    | $2         |
| PDF                                               | $0.003                                    | $3         |
| Actor start (once per run)                        | $0.004 per run at the default 2 GB memory | —          |
| Residential proxy traffic (only if you choose it) | $0.015 per MB                             | $15 per GB |

Failed pages are free. Platform usage and datacenter proxy are included.

For example, 500 PNG screenshots in one run cost about **$1.00**.

Residential proxy is only needed for sites that block data centers. A typical page uses 1–5 MB, so with residential proxy each screenshot costs roughly $0.015–0.075 extra. When residential proxy is used, each output item gets a `residentialProxyMb` field with that page's traffic.

### FAQ

**What's the difference between JPG and JPEG?** None, it's the same format. Pick whichever file extension you prefer.

**Why is my full-page screenshot cut off?** Pages taller than **Max full-page height** (15,000 px by default) are cut, to keep files small and avoid memory errors. You can raise the limit to 30,000 px. The `truncated` field in the output tells you when this happened.

**A cookie banner is still visible.** Add its CSS selector to **Hide elements**, or let us know in the Issues tab so we can add it to the built-in list.

**The page looks empty or half-loaded.** Set **Wait until** to *Network idle*, add a **Delay** of a few seconds, or use **Wait for element** with a selector that appears once the content is ready.

**Can I capture pages behind a login?** Yes, if you have a session cookie: pass it in **Cookies**. Only do this for accounts you own.

**Can I screenshot local or internal addresses?** No. For security, `localhost` and private network addresses are blocked.

# Actor input Schema

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

Websites to capture. One screenshot is taken per URL. URLs without http(s):// get https:// added.

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

File type of the result. JPG and JPEG are the same format.

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

Capture the whole scrollable page instead of only the visible viewport.

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

Browser window width in pixels.

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

Browser window height in pixels. Also the screenshot height when Full page is off.

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

Image quality for JPEG/JPG, from 1 to 100. Ignored for PNG and PDF.

## `scaleFactor` (type: `integer`):

Device pixel ratio. 2 gives a sharp retina image twice the viewport size.

## `hideAds` (type: `boolean`):

Block ads and trackers before taking the screenshot.

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

Hide cookie consent popups and GDPR notices.

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

CSS selectors of elements to hide, e.g. .chat-widget or #newsletter-popup.

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

Ask the website to use its dark theme (prefers-color-scheme: dark).

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

When the page counts as ready. The screenshot always waits for the page's HTML; Load event and Network idle add up to 10 extra seconds, then the screenshot is taken anyway. DOM ready is fastest.

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

Extra seconds to wait after the page loads, e.g. for animations.

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

Wait until an element matching this CSS selector is visible before capturing.

## `scrollPage` (type: `boolean`):

For full-page screenshots and PDFs, scroll through the page first so lazy-loaded images appear.

## `timeout` (type: `integer`):

Maximum seconds to wait for the page to load.

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

CSS selector of a single element to screenshot instead of the page. Not used for PDF.

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

Full-page screenshots taller than this are cut, to avoid huge files and memory errors.

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

Custom User-Agent header. Leave empty for a regular desktop Chrome.

## `headers` (type: `object`):

Headers sent with every request, e.g. {"Accept-Language": "de-DE"}.

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

Cookies to set before loading, e.g. \[{"name": "session", "value": "abc"}]. Domain defaults to the URL's domain.

## `css` (type: `string`):

CSS injected into the page before capturing.

## `js` (type: `string`):

JavaScript run in the page before capturing, e.g. to click a tab.

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

Paper size for PDF output.

## `pdfLandscape` (type: `boolean`):

Use landscape orientation for PDF.

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

Include background colors and images in the PDF.

## `maxConcurrency` (type: `integer`):

How many pages to capture in parallel. The actor also scales down automatically if memory runs low.

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

No proxy is fastest. Use a proxy for sites that block data-center traffic or show different content by country. Datacenter proxy is included in the price. Residential proxy traffic is charged extra, per MB.

## Actor input object example

```json
{
  "urls": [
    {
      "url": "https://apify.com"
    }
  ],
  "format": "png",
  "fullPage": false,
  "width": 1920,
  "height": 1080,
  "quality": 80,
  "scaleFactor": 1,
  "hideAds": true,
  "hideCookieBanners": true,
  "darkMode": false,
  "waitUntil": "load",
  "delay": 0,
  "scrollPage": true,
  "timeout": 60,
  "maxHeight": 15000,
  "pdfPageSize": "A4",
  "pdfLandscape": false,
  "pdfPrintBackground": true,
  "maxConcurrency": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

One item per URL with status, download link, size, HTTP status and page title.

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

The PNG, JPEG or PDF files themselves, stored in the run's key-value store.

# 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": [
        {
            "url": "https://apify.com"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("ttechx/website-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": [{ "url": "https://apify.com" }],
    "proxyConfiguration": { "useApifyProxy": False },
}

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ttechx/website-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/CkspoJO609mv2T2KK/builds/bWjTvnYrmJd7dFnkC/openapi.json
