# Website Screenshot API: Full-Page PNG, JPEG and PDF Captures (`rowcraft/website-screenshot-api`) Actor

Capture full-page or viewport screenshots of any public web page as PNG, JPEG or WebP, with an optional A4 PDF. Desktop or mobile width, cookie banners hidden, robots.txt obeyed, and you pay only for each image saved.

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

## Pricing

from $0.60 / 1,000 screenshots

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

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 API: Full-Page PNG, JPEG and PDF Captures

Take a **website** screenshot of any public page by giving the actor a list of addresses. It opens each page in a real Chromium browser, waits until the page has settled, hides the cookie banner, and saves a full-page, window-sized or single-element picture as PNG, JPEG or WebP, with an A4 PDF on request. You get one dataset row per picture with the page title, the image size and a direct download link, as JSON, CSV or Excel, and the files themselves in the key-value store of the run.

It is built for the jobs that come back every week: visual archives of competitor pages, pictures of landing pages for reports and tickets, mobile and desktop previews, thumbnails for a directory, and proof of what a page looked like on a given day. It respects robots.txt, never logs in and never clicks anything on the page, and it charges only for pictures that were actually saved.

![Input form of Website Screenshot API: Full-Page PNG, JPEG and PDF Captures](https://api.apify.com/v2/key-value-stores/7hbQFQdGq61v2OZ2h/records/website-screenshot-api-input.png)

### What you get

One row per saved screenshot:

- **The page:** the address you gave, the address after redirects, the HTTP status and the page title
- **The picture:** format, width and height in pixels, size in bytes, and `screenshotUrl`, a download link to the file in the key-value store of the run
- **How it was taken:** full page or not, desktop or mobile view, the CSS selector if you captured one element, and `truncated` when a very tall page was cut at 16,000 pixels
- **The PDF (optional):** `pdfUrl`, a link to an A4 PDF of the same page, included in the price of the screenshot
- **Timing:** how many milliseconds the capture took and when it was taken

The run also writes a `COVERAGE` record with one line per address you asked for (ok, blocked, robots_disallowed, not_found, timeout, error or not_checked, with the reason) and a `RUN_SUMMARY` with the counts, the average capture time, the browser version and any warnings.

### Why this actor

- **Pay for pictures, not attempts.** A page that times out, answers with an anti-bot page, returns an HTTP error or is refused by robots.txt is listed in `COVERAGE` and costs nothing. So do duplicates and invalid entries.
- **Clean pictures by default.** Common cookie banners and consent pop-ups are hidden with CSS before the capture, tracking and analytics scripts are not loaded (images, fonts and styles are), and lazy images are scrolled into view so a long page is not full of blank boxes.
- **One input for every shape.** Full page, the window only, or one element picked by a CSS selector; desktop or phone; 1x to 3x pixel ratio; PNG, JPEG or WebP; an optional PDF.
- **Polite by design.** robots.txt is read for every site (and for every redirect target) before the page is opened, requests to the same site are spaced out, and the visit carries a user agent that names Rowcraft so site owners can recognise it.
- **Fast.** One browser per run, a fresh isolated context for each page, two pages at a time by default. In our test runs a typical page took two to four seconds.
- **Built for schedules.** Turn on **Only new addresses** and a scheduled run captures only the addresses it has not delivered before; a webhook tells you when it finishes.

### How to use it

1. Open the Actor and fill in **Website URLs** (the other fields are optional filters).
2. Set **Maximum screenshots** to a small number for a first try (the default is a safe start).
3. Click **Start**. The status line shows progress; the run stops cleanly at your limit or at the charge limit you set in the run options.
4. Open the **Dataset** tab and download JSON, CSV, Excel, XML or HTML, or send the rows to Google Sheets, Slack, Make, n8n or Zapier with the Integrations tab.
5. To run it on a schedule, use **Schedules** in Apify Console and turn on **Only new rows since the last run** below: every run then costs only the new rows, and a webhook URL tells you when something new came in.

For the first try keep the list short. The picture of each address is in the key-value store of the run, under the key that ends `.png`, `.jpg` or `.webp` (and `.pdf`); the same link is in the `screenshotUrl` and `pdfUrl` columns of the dataset.

### Input

| Field | What it does |
|---|---|
| `urls` | Pages to capture, one per line: a full address (`https://example.com/pricing`) or a domain (`example.com`). Up to 100,000 per run. |
| `format` | `png` (lossless, default), `jpeg` or `webp`. |
| `fullPage` | Capture the whole scrollable page (default on) or only the window. Pages taller than 16,000 px are cut at that height. |
| `width`, `height` | Window size in pixels. Default 1280 x 800 on desktop, 390 x 844 on mobile. |
| `mobile` | Open the page as a phone: touch device, mobile Chrome user agent, 390 px wide unless you set a width. |
| `deviceScaleFactor` | Pixel ratio 1 to 3. Use 2 for retina-sharp pictures; the file has 4 times the pixels. |
| `quality` | 1 to 100 for JPEG and WebP (default 80). |
| `selector` | A CSS selector: only the first matching visible element is captured. |
| `pdf` | Also save an A4 PDF of the page (up to 50 pages). |
| `delayMs` | Extra wait after the page has loaded, for late animations or widgets. |
| `timeoutMs` | Longest time to let a page load (default 20 s). |
| `hideCookieBanners` | Hide the common consent banners with CSS (default on). Nothing is clicked. |
| `scrollToLoad` | Scroll through a full-page capture once so lazy images appear (default on). |
| `maxItems` | Stop after this many saved screenshots. 0 = the whole list. |
| `onlyNew`, `stateName` | Capture only addresses not delivered in an earlier run with the same state name. |
| `notifyUrl`, `notifyWhenEmpty` | A webhook that receives one message when the run ends; see **Automation** below. |
| `maxConcurrency` | Pages open at the same time, 1 to 4 (default 2). |
| `requestIntervalMs` | Pause between page loads to the same site, default 1000 ms, minimum 250 ms. |

Example: three pages as full-page PNG files.

```json
{
  "urls": ["https://example.com", "https://www.wikipedia.org", "https://developer.mozilla.org"]
}
```

Example: phone previews as small JPEG files, with a PDF of each page.

```json
{
  "urls": ["https://www.python.org", "https://nodejs.org"],
  "mobile": true,
  "format": "jpeg",
  "quality": 70,
  "pdf": true
}
```

Example: only the infobox of three articles, as WebP.

```json
{
  "urls": ["https://en.wikipedia.org/wiki/France", "https://en.wikipedia.org/wiki/Germany"],
  "selector": ".infobox",
  "format": "webp"
}
```

### Output

18 fields per row. Empty values are `null`, never missing, so CSV and Excel columns are stable.

| Field | Type | Example |
|---|---|---|
| `id` | string | `https://developer.mozilla.org/` |
| `url` | string | `https://developer.mozilla.org/` |
| `finalUrl` | string | `https://developer.mozilla.org/en-US/` |
| `statusCode` | integer | 200 |
| `title` | string | MDN Web Docs |
| `width` | integer | 1280 |
| `height` | integer | 3232 |
| `format` | string | png |
| `bytes` | integer | 470323 |
| `fullPage` | boolean | True |
| `mobileView` | boolean | False |
| `selector` | string | CSS selector of the element captured, or null |
| `truncated` | boolean | False |
| `screenshotUrl` | string | `https://api.apify.com/v2/key-value-stores/abc123/records/screenshot…` |
| `pdfUrl` | string | Download link of the PDF, or null when no PDF was asked for or it failed |
| `tookMs` | integer | 3390 |
| `capturedAt` | string | 2026-10-17T08:16:43.973Z |
| `error` | string | Problem with an extra output (for example the PDF) when the picture itself was saved, else null |

#### Example rows

Two real rows from a run (long texts shortened here, complete in the dataset):

```json
[
  {
    "id": "https://developer.mozilla.org/",
    "url": "https://developer.mozilla.org/",
    "finalUrl": "https://developer.mozilla.org/en-US/",
    "statusCode": 200,
    "title": "MDN Web Docs",
    "width": 1280,
    "height": 3232,
    "format": "png",
    "bytes": 470323,
    "fullPage": true,
    "mobileView": false,
    "selector": null,
    "truncated": false,
    "screenshotUrl": "https://api.apify.com/v2/key-value-stores/ecc3ab23-88c3-4df1-a99b-aae57e923bd7/records/screenshot-630a82fd-developer-mozilla-org.png",
    "pdfUrl": "https://api.apify.com/v2/key-value-stores/ecc3ab23-88c3-4df1-a99b-aae57e923bd7/records/screenshot-630a82fd-developer-mozilla-org.pdf",
    "tookMs": 3926,
    "capturedAt": "2026-10-17T08:26:34.041Z",
    "error": null
  },
  {
    "id": "https://www.wikipedia.org/",
    "url": "https://www.wikipedia.org/",
    "finalUrl": "https://www.wikipedia.org/",
    "statusCode": 200,
    "title": "Wikipedia",
    "width": 390,
    "height": 1580,
    "format": "jpeg",
    "bytes": 78182,
    "fullPage": true,
    "mobileView": true,
    "selector": null,
    "truncated": false,
    "screenshotUrl": "https://api.apify.com/v2/key-value-stores/f41fb955-8406-42ec-a30c-728f79ebcfc4/records/screenshot-72e64cab-wikipedia-org.jpg",
    "pdfUrl": null,
    "tookMs": 2542,
    "capturedAt": "2026-10-17T08:26:37.673Z",
    "error": null
  }
]
```

Results can be downloaded as JSON, CSV, Excel, XML or HTML from the Dataset tab, or read through the Apify API.

![Results of Website Screenshot API: Full-Page PNG, JPEG and PDF Captures in the Apify dataset view](https://api.apify.com/v2/key-value-stores/7hbQFQdGq61v2OZ2h/records/website-screenshot-api-results.png)

### Pricing

**Pay per result.** You pay for each screenshot saved and delivered to your dataset, nothing else: no subscription, no minimum, no charge for pages that could not be captured (timeout, anti-bot page, robots.txt, HTTP errors), for invalid or repeated entries, or for addresses skipped by **Only new addresses**. The PDF of a page is included in the price of its screenshot.

| Your Apify plan | Price per 1,000 rows | Price per row |
|---|---|---|
| Free plan | **$0.80** | $0.0008 |
| Starter plan | **$0.70** | $0.0007 |
| Scale plan | **$0.65** | $0.00065 |
| Business plan and above | **$0.60** | $0.0006 |

Example: 1,000 screenshots cost $0.80 on the Free plan and $0.60 on the Business plan. A start event of $0.00005 is charged once per run (Apify default).

**Platform usage is separate and is not small for a browser.** Apify bills the compute and storage of every run on top of the price per screenshot. This actor runs a Chromium browser in 1,024 MB. As an estimate, not a promise, expect about $0.10 to $0.40 of platform usage per 1,000 screenshots at two to four seconds each, depending on how heavy the pages are and on your plan; the **Usage** of each run in Console shows the real figure. Turning off the PDF, using JPEG or WebP for long pages, and leaving `maxConcurrency` at 2 keep it low.

**Cap your spend:** set *Maximum total charge* in the run options. The actor stops cleanly when the cap is reached and you keep everything delivered until then. The run summary (`RUN_SUMMARY` in the key-value store) says why a run stopped.

### Automation: only new addresses, notifications, schedules

**Only new addresses since the last run.** Turn on `onlyNew` and the actor remembers every address it delivered to you (in a key-value store named `rowcraft-website-screenshot-api-state` in your Apify account). The next run with the same `stateName` skips those addresses and you pay only for new ones. It remembers the address, not the settings: if you change the width, the format or the selector and want fresh pictures of the same pages, use a different `stateName`. The first run captures everything it can. Use a different `stateName` for each list or schedule so they keep separate memories.

**Notification when the run ends.** Put a webhook address in `notifyUrl` and the actor sends one JSON POST with the number of delivered screenshots, links to the dataset (JSON and CSV) and the run. It works with Slack and Discord incoming webhooks (the message is in `text` and `content`), with Make, n8n and Zapier catch hooks, and with your own endpoint. By default it is sent only when at least one screenshot was saved; `notifyWhenEmpty` sends it every time.

**Schedules.** Create a schedule in Apify Console (hourly, daily, weekly or cron). For a visual archive of pages that must be photographed again every time, leave `onlyNew` off and the schedule produces a fresh set of pictures each run; for a growing list of pages where each should be captured once, turn it on.

**Integrations.** Send the rows, with their image links, to Make, n8n, Zapier, Google Sheets, Slack, Google Drive, Airtable or any webhook from the Integrations tab of the Actor, with no code.

**API, SDKs and AI agents.** Every run is available through the Apify API and the official JavaScript and Python clients. A call can wait for the run and read the dataset, then download each `screenshotUrl`. The Actor can also be called by AI agents through the Apify MCP server. The example input in the API tab is a working call.

### Use cases

- **Visual archive of competitor pages:** a weekly schedule over their pricing and landing pages gives you a dated picture of every change, in the same width every time.
- **Reports and tickets:** drop the `screenshotUrl` into a report, an issue or a client update instead of pasting browser screenshots by hand.
- **Mobile and desktop previews:** run the same list twice, once with `mobile` on, and compare how a page looks on a phone and on a laptop.
- **Thumbnails for a directory or a catalogue:** a window-sized JPEG of each site, with a quality setting that keeps the files small.
- **Evidence of a page's state:** the picture, the title, the status code and the capture time in one row.
- **One block of a page:** a pricing table, a chart or a product card, captured alone with a CSS selector.
- **Printable copies:** the optional A4 PDF of a page for records.

Ready-made examples, each with the input filled in (open one and press Start, or save it as your own task):

- [Take mobile screenshots of documentation websites](https://apify.com/rowcraft/website-screenshot-api/examples/mobile-screenshots-of-documentation-sites)
- [Save full-page PNG and PDF copies of web pages](https://apify.com/rowcraft/website-screenshot-api/examples/full-page-png-and-pdf-of-web-pages)
- [Capture one element of a web page as a WebP image](https://apify.com/rowcraft/website-screenshot-api/examples/capture-one-element-of-a-page-as-webp)

### What this actor does not do

- Log in, fill in forms or click: pages behind a login, a paywall or a pop-up that must be accepted show what any new visitor sees. The cookie banner is hidden, never accepted.
- Solve CAPTCHAs or get around anti-bot protection: a page that answers with a challenge or an access-denied page is reported as `blocked` and not charged.
- Use proxies or hide where it runs: every page is opened from the Apify platform's own network.
- Open private or local addresses: addresses that resolve to a private network (localhost, 10.x, 192.168.x, 169.254.x and similar) are refused on the platform.
- Wait for a page forever: a page that has not loaded within the page timeout is a `timeout`, and a page that keeps the network busy is captured after at most ten more seconds.
- Crawl: it captures the addresses you list, never links found on the pages.
- Record video, play media or capture a page after scripted steps such as typing in a search box.
- Read the text or the data of the page: the row holds the title and the picture link, nothing else from the page.

### Limits and fair use

- **Pace.** Requests to the same site are spaced at least 1,000 ms apart by default (minimum 250 ms); different sites are not delayed. Two pages are open at once by default.
- **Page height.** Pictures are at most 16,000 pixels high (at pixel ratio 1; 8,000 page pixels at ratio 2, 5,333 at ratio 3). A taller page is cut there and its row has `truncated: true`, with a warning in the run summary.
- **Page width.** The picture is as wide as the window. Content that sticks out to the right of the window is not included.
- **What is captured is what a visitor sees after the page has settled.** The actor waits for the page's load event, then for the network to go quiet for half a second, up to ten seconds, and then for `delayMs`. Content that appears later, after a long animation or on a user action, needs a longer `delayMs` or cannot be captured.
- **Sticky and fixed elements** (headers, chat buttons) are drawn where the browser puts them: at the top of a full-page picture, or over the content in a window-sized one.
- **Anti-bot pages.** Websites behind a bot challenge (Cloudflare, Akamai, DataDome and similar) are reported as `blocked` and not charged. After 10 blocked pages in a row the run stops and says why in the run summary, because the rest of the list would most likely be blocked too.
- **robots.txt is obeyed** for every address the visit touches in the main window, including redirect targets. If robots.txt disallows the address, the page is `robots_disallowed`; if robots.txt answers with a server error, the page is not opened, as the robots.txt standard (RFC 9309) requires.
- **Memory.** The run uses 1,024 MB. Very heavy pages, very tall pages at pixel ratio 3 and more than two pages at a time need more memory: raise it in the run options together with `maxConcurrency`.
- **Up to 100,000 addresses per run.** The run stops two minutes before its timeout with the summary, the coverage and the **Only new addresses** memory saved.

### Data source and licence

There is no third-party data source: the actor opens the addresses you give it and saves what each page shows to a visitor, after checking robots.txt. The pictures belong to the people who made the pages; the actor gives you a copy of what was publicly shown, and whether you may keep, publish or reuse it depends on the page and on the law that applies to you. The rows contain the address, the title, the size of the picture and its link, and nothing else from the page.

The browser is Chromium, driven with Playwright. Rowcraft is independent and not affiliated with or endorsed by the makers of Chromium or Playwright, or by the websites the actor opens. The visit identifies itself with a Chrome user agent that ends with `Rowcraft-Screenshot/1.0 (+https://apify.com/rowcraft)`; robots.txt is read under the product token `rowcraft`.

### Privacy: no personal data

Rowcraft actors are built not to collect personal data:

- The rows hold no names, e-mail addresses, phone numbers or other fields about people. An e-mail address or phone number inside a page title is removed from the row.
- The picture is a different matter: it shows whatever the page shows to every visitor, which can include names or photos that the page's owner published. You choose the pages, so you are responsible for what you capture and keep.
- Each page is opened in a fresh browser context with no cookies, no login and no stored data, and the context is deleted after the capture.
- The actor sends no form data, stores nothing about the pages outside your run and your own **Only new addresses** memory, and does not open private network addresses.

### Other Rowcraft actors

All Rowcraft actors read official or public sources, deliver flat rows without personal data and support only-new runs and notifications:

- [Ashby Jobs Scraper – Job Postings with Salary Ranges](https://apify.com/rowcraft/ashby-jobs-scraper) — Job postings from Ashby job boards (jobs.ashbyhq.com) by company: title, department, team, locations with country, employment and workplace type, published salary range, full text.
- [Broken Link Checker – Find 404s and Dead Links API](https://apify.com/rowcraft/broken-link-checker) — Pay per crawled page, not per link: crawl a site within robots.txt and check every link on each page for 404s, 5xx errors, DNS and TLS failures and redirects.
- [Bulk Image Downloader API: Save Page Images with Sizes](https://apify.com/rowcraft/bulk-image-downloader) — Download the images of any web pages, or direct image links, into a key-value store with width, height, format, size and a download link per file.
- [Career Site Jobs Scraper: Greenhouse, Lever, Ashby, Workday](https://apify.com/rowcraft/career-site-jobs-scraper) — Job listings from the career pages of the companies you choose on Greenhouse, Lever, Ashby, Workday, Workable, Personio, Recruitee, Teamtailor and Gem, in one run and one format: title, locations, department, salary when published, full text.
- [Chrome Web Store Scraper: Users, Ratings & Versions](https://apify.com/rowcraft/chrome-web-store-scraper) — Reads public Chrome Web Store listing pages with no login, no proxy and no personal data: users, rating, category, version, update date, permissions and company developers.
- [Domain Email and DNS Checker API: MX, SPF, DMARC, Providers](https://apify.com/rowcraft/domain-email-dns-checker) — Find which email provider, sending services and DNS host each domain uses, from public DNS records only.
- [SIRENE France Company Scraper: SIREN, NAF, Revenue, Status](https://apify.com/rowcraft/france-company-register) — French companies from the official Recherche d'entreprises API (INSEE SIRENE + INPI): SIREN and SIRET, legal form, NAF activity, head-office address, employee band, revenue and net income, labels, creation date and VAT number.
- [Gem Jobs Scraper – Job Board Listings from jobs.gem.com](https://apify.com/rowcraft/gem-jobs-scraper) — Job listings from Gem job boards (jobs.gem.com) by company: title, department, offices with country, employment type, remote, hybrid or on-site, requisition ID, publication date and full ad text, from the public Gem Job Board API.
- [Google Play Apps Scraper: App Details, Installs, Ratings](https://apify.com/rowcraft/google-play-apps-scraper) — Public Google Play app details as flat rows: installs, rating, number of ratings, price, version, last update, minimum Android, ads and in-app purchases.
- [Greenhouse Jobs Scraper – Job Listings by Company Board](https://apify.com/rowcraft/greenhouse-jobs-scraper) — Job listings from Greenhouse job boards by company: title, departments, offices, publication date, full ad text, published pay ranges.
- [Himalayas Jobs Scraper: Remote Jobs API with Salaries](https://apify.com/rowcraft/himalayas-jobs-scraper) — Remote jobs from Himalayas through its public jobs API: title, company, salary range, seniority, categories, the countries and time zones open to candidates, full description and job link.
- [KRS Poland Companies Scraper: Register Data, PKD, Status](https://apify.com/rowcraft/krs-poland-companies) — Polish companies from the official KRS register API of the Ministry of Justice: name, KRS, NIP and REGON numbers, legal form, status, address, PKD activity codes, share capital, branches and registration dates.
- [LEI Records Scraper: Legal Entity Identifier Lookup API](https://apify.com/rowcraft/lei-records-scraper) — Legal Entity Identifier (LEI) records from the Global LEI Index, read through the public GLEIF API: legal name, legal form, register number, addresses, status, renewal date and parent companies.
- [Lever Jobs Scraper – Job Postings from jobs.lever.co](https://apify.com/rowcraft/lever-jobs-scraper) — Job postings from Lever career pages (jobs.lever.co) by company: title, team, department, location, commitment, workplace type, salary range when published, description, requirements and benefits.
- [Norway Company Register Scraper: Brønnøysund Business Data](https://apify.com/rowcraft/norway-company-register-scraper) — Norwegian companies from the Central Coordinating Register for Legal Entities (Brønnøysund, NLOD open data): organisation number, legal form, industry, employees, share capital, addresses, website, VAT and bankruptcy status.
- [PDF Text Extractor: Text, Pages and Metadata from PDF Links](https://apify.com/rowcraft/pdf-text-extractor) — Get the text of every PDF you link, page by page, with page count, language and word count.
- [Personio Jobs Scraper: Job Listings, Salaries, Departments](https://apify.com/rowcraft/personio-jobs-scraper) — Job ads from any company's Personio careers feed: title, department, office, employment type, schedule, seniority, salary when published, keywords and the full description in the language you choose.
- [Platsbanken Scraper: Sweden Jobs, Employers, Org Numbers](https://apify.com/rowcraft/platsbanken-jobs-scraper) — Every job ad on Platsbanken (Arbetsförmedlingen) from the official JobTech API: headline, employer and organisation number, occupation codes, municipality, coordinates, salary type, deadline and full text.
- [Recruitee Jobs Scraper – Job Listings by Company Career Site](https://apify.com/rowcraft/recruitee-jobs-scraper) — Job listings from Recruitee career sites by company: title, department, locations with country, employment type, remote flag, published salary and full text, one request per company.
- [Robots.txt and AI Crawler Access Checker API](https://apify.com/rowcraft/robots-ai-crawler-checker) — Check which AI and search crawlers a website lets in: GPTBot, ClaudeBot, PerplexityBot, Google-Extended and more, read from robots.txt by the RFC 9309 rules.
- [RSS Feed Finder and Reader – Blog and News Article API](https://apify.com/rowcraft/rss-feed-finder-reader) — Find the RSS, Atom and JSON feeds of any website and read their newest articles, from a domain name alone.
- [SEO Audit Tool: Titles, Meta Tags, Headings and Links API](https://apify.com/rowcraft/seo-audit-tool) — Audit the on-page SEO of any list of pages or websites: titles, meta descriptions, headings, canonicals, indexing, links, images and structured data, with a score and the issues found per page.
- [Shopify Products Scraper: Store Catalog Export to JSON, CSV](https://apify.com/rowcraft/shopify-products-scraper) — Products from any Shopify store's public catalog: title, vendor, type, tags, description, variants with price, compare-at price, SKU and stock, images, options, store currency.
- [Sitemap URL Extractor: Every Page with Last-Modified Dates](https://apify.com/rowcraft/sitemap-url-extractor) — Get every page a site lists in its sitemaps, with last-modified dates, from robots.txt through sitemap indexes and .gz files.
- [SSL Certificate and Security Headers Checker API](https://apify.com/rowcraft/ssl-security-headers-checker) — Check the TLS certificate and the HTTP security headers of every domain in one run, with an A+ to F grade and the exact issues to fix.
- [Store Products Scraper – Shopify, WooCommerce, VTEX](https://apify.com/rowcraft/store-products-scraper) — Export the product catalogue of any Shopify, WooCommerce or VTEX store from its public catalogue endpoint: title, brand, prices, discounts, stock, categories, images and links, one row per product, the same columns on every platform.
- [Structured Data Extractor: JSON-LD, Schema.org, Open Graph](https://apify.com/rowcraft/structured-data-extractor) — Pull the schema.org JSON-LD, Microdata, RDFa and Open Graph of any page list into flat rows: types, product price, availability, ratings, organization, breadcrumbs, with validation issues.
- [Teamtailor Jobs Scraper – Career Site Jobs by Company](https://apify.com/rowcraft/teamtailor-jobs-scraper) — Job listings from Teamtailor career sites by company: title, department, role, locations with city and country, remote or hybrid status, publication date and full ad text, from the official job feed.
- [TED Tenders Scraper: EU Public Procurement Notices API](https://apify.com/rowcraft/ted-tenders-scraper) — EU public procurement notices from TED (Tenders Electronic Daily), the official EU tenders portal, through its public Search API: title, buyer, country, CPV codes, values, deadlines, lots and document links.
- [UK Companies House Scraper: Company Search & Profiles API](https://apify.com/rowcraft/uk-companies-house-scraper) — UK companies from the official Companies House API with your free key: search by name, status, type, SIC code, date or location, or look up company numbers.
- [UK Tenders Scraper: Find a Tender + Contracts Finder API](https://apify.com/rowcraft/uk-tenders-scraper) — UK public procurement notices from Find a Tender and Contracts Finder, the official UK government portals, through their open OCDS APIs: title, buyer, region, CPV codes, values, deadlines, notice type and links.
- [Bulk URL Status and Redirect Chain Checker API](https://apify.com/rowcraft/url-status-redirect-checker) — Check the status code, redirect chain, canonical and indexing signals of every URL in a list, with the final destination and a loop flag.
- [VTEX Products Scraper – Public Catalog Export](https://apify.com/rowcraft/vtex-products-scraper) — Export the catalogue of any VTEX store (Auchan, Chedraui and thousands of retailers in Europe and Latin America) from its public search endpoint: title, brand, EAN, prices, list prices, stock, categories, specifications and images, one row per product.
- [Website to Markdown Extractor: Clean Text for LLMs and RAG](https://apify.com/rowcraft/website-markdown-extractor) — Turn a list of web page addresses into clean Markdown and plain text for LLMs and RAG: the main content only, with headings, links, images and tables.
- [Website Tech Stack Detector – Technology Lookup API](https://apify.com/rowcraft/website-tech-stack-detector) — Find the technologies behind a list of websites: CMS, e-commerce platform, analytics, tag managers, ad pixels, consent tools, chat, CDN and payments, from one polite home-page request per domain.
- [WooCommerce Products Scraper – Store API Export](https://apify.com/rowcraft/woocommerce-products-scraper) — Export every product of a WooCommerce store through its public Store API: title, SKU, prices and sale prices, stock, categories, tags, attributes, ratings, images and links, one row per product.
- [Workable Jobs Scraper: Job Listings from Career Pages](https://apify.com/rowcraft/workable-jobs-scraper) — Job listings from any company's Workable career page: title, department, location, remote or on-site, employment type, description, requirements, benefits and salary when published.
- [Workday Jobs Scraper – Jobs from myworkdayjobs.com Sites](https://apify.com/rowcraft/workday-jobs-scraper) — Job listings from Workday career sites (myworkdayjobs.com) by company: title, locations, country, posting date, time type, requisition ID and the full description.

### FAQ

**How much does it cost?** $0.80 per 1,000 screenshots on the Free plan and $0.60 on the Business plan, only for pictures that were saved (see Pricing). Apify bills the platform usage of the run separately; set a maximum total charge in the run options to cap a run.

**Why is my screenshot blank or missing content?** The page was captured as it stood after its load event and a short quiet period. If the page builds itself slowly with scripts, raise `delayMs` (try 2000 to 5000). If images are missing, keep `scrollToLoad` on for full-page pictures. If the picture shows an error or a challenge page, look at the row's `statusCode` and at the `COVERAGE` record. Pages that need a login or a click to show content cannot be captured.

**Why is there a cookie banner in my screenshot, or why is something hidden that should be there?** Hiding works by CSS for the common consent platforms and for elements whose id or class names say cookie banner or consent banner. A banner with an unusual name stays visible; set `hideCookieBanners` to false and use `selector` or a different page address if it is in the way. In rare cases a page element with "cookie-consent" in its class name is real content and is hidden with the banners; turn the option off for that page.

**How long are the files kept?** In the default key-value store of the run, which Apify keeps for the retention period of unnamed storages (7 days at the time of writing; the Apify documentation has the current figure). Download the files you need, or copy them to your own storage or cloud bucket, before then. The dataset rows follow the same retention.

**Who can open the download links?** The links in `screenshotUrl` and `pdfUrl` point to files in the run's key-value store. On the Apify platform they carry a signature, so they open without logging in for as long as the files exist; the same files are listed in the **Storage** tab of the run.

**Why is the result empty?** Every address in the list could not be captured, or was skipped. The `COVERAGE` record gives the reason per address: an anti-bot page (`blocked`), robots.txt (`robots_disallowed`), no website or an HTTP 404 (`not_found`), a page that did not load in time (`timeout`), an invalid entry or another problem (`error`). With **Only new addresses** on, addresses delivered in an earlier run are skipped. Nothing is charged for any of those, apart from the start event.

**Is it legal?** The actor opens public pages as any visitor's browser would, obeys robots.txt, never logs in and does not collect personal data in its rows. Whether and how you may use a picture of a page (for example in a publication or for marketing) depends on the page's owner and on the law that applies to you.

**Does it collect personal data?** No personal data in the rows: no names, e-mail addresses or phone numbers. A picture can show what the page shows, so choose pages with care. See the Privacy section.

**Do I pay for pages that fail?** No. Timeouts, blocked pages, robots.txt refusals, HTTP errors, a selector that matches nothing, invalid entries and duplicates are never charged. A row exists only when the picture was saved. If a PDF was asked for and fails while the picture succeeds, you get the row with `pdfUrl` empty and the reason in `error`, and you pay for the picture.

**Can I capture a phone view?** Yes: turn on `mobile`. The window is 390 pixels wide unless you set `width`, the page sees a touch device and a mobile Chrome user agent, and many sites then serve their mobile layout.

**Can I capture only a part of a page?** Yes: give a CSS selector in `selector`. The first visible match is captured on its own. If nothing visible matches within three seconds the address is reported as an error and not charged.

**What is the maximum size of a picture?** 16,000 pixels in height at pixel ratio 1, and as wide as the window (up to 3,840 pixels). A taller page is cut and marked `truncated`.

**How does Only new addresses work here?** The actor remembers the addresses it delivered to you. The next run with the same state name skips them, so a list that grows over time costs only the new pages. It does not compare the pages' content; to photograph the same pages again, leave the option off or change the state name.

**Why do some sites return a blocked page?** Sites that use bot protection often refuse automated browsers, from any provider. The actor does not try to get around that: the page is reported as blocked and is not charged.

### Support and reviews

**Problems, missing fields, questions:** open an issue on the **Issues** tab of this Actor. We answer within one working day and fix confirmed bugs in the next release; the changelog lists every change.

If this Actor saved you time, a short review on its page helps other users find it and helps us keep improving it.

# Changelog

This Actor's version history is a separate document: https://apify.com/rowcraft/website-screenshot-api/changelog.md

# Actor input Schema

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

Pages to capture, one per line: a full address (https://example.com/pricing) or just a domain (example.com). Duplicates and invalid entries are skipped and never charged.

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

PNG is lossless and the sharpest; JPEG and WebP are much smaller for long pages (set the quality below).

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

Capture the whole scrollable page. Turn it off to capture only what fits in the window (width x height below). Ignored when a CSS selector is given. Pages taller than 16,000 px are cut at that height.

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

Width of the browser window in pixels. Default 1280 on desktop, 390 when Mobile view is on. Between 200 and 3840.

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

Height of the browser window in pixels: the size of the picture when Full page is off. Default 800 on desktop, 844 on mobile. Between 200 and 4000.

## `mobile` (type: `boolean`):

Open the page as a phone does: touch device, mobile Chrome user agent and, unless you set a width, a 390 px wide window. Many sites then serve their mobile layout.

## `deviceScaleFactor` (type: `integer`):

1 = one image pixel per page pixel. 2 or 3 give sharper pictures for retina screens, with 4 to 9 times as many pixels (bigger files, a lower page-height limit).

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

From 1 (smallest file) to 100 (best picture). Used for JPEG and WebP only; PNG is always lossless.

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

Capture only the first element that matches this CSS selector (for example `#pricing` or `main article`) instead of the page. The row is not created when nothing visible matches.

## `pdf` (type: `boolean`):

Save an A4 PDF of the page (print layout, backgrounds included, up to 50 pages) next to the picture. Included in the price of the screenshot; the link is in `pdfUrl`.

## `delayMs` (type: `integer`):

Wait this long after the page has loaded, for animations, late widgets or slow scripts. 0 = no extra wait. The actor already waits for the network to go quiet.

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

Longest time to let a page load. A page that has not loaded by then is reported as a timeout and not charged. After the load the actor waits up to 10 more seconds for the network to go quiet.

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

Hide the common cookie-consent banners and pop-ups with CSS before the capture. Nothing is clicked or accepted on the page.

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

For full-page captures, scroll down the page once (and back) so images that load on scroll appear in the picture. Adds about a second on long pages. It scrolls only; it never clicks.

## `maxItems` (type: `integer`):

Stop after this many screenshots are saved and delivered. 0 = the whole list.

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

How many pages are open at once (1 to 4). The default 2 suits the 1 GB of memory of the run; raise it only together with the run's memory. Requests to the same site are still spaced out.

## `onlyNew` (type: `boolean`):

Remember the rows already delivered to you (in a key-value store in your Apify account) and deliver only rows that appeared since the last run with the same state key. The first run delivers everything that matches; later runs cost only the new rows. Ideal for schedules.

## `stateName` (type: `string`):

Name of the memory used by "Only new rows". Use a different name for each schedule or search (for example `stockholm-python`) so they do not share one memory.

## `notifyUrl` (type: `string`):

A webhook address that receives one JSON POST with the number of new rows and links to the dataset: a Slack or Discord incoming webhook, a Make, n8n or Zapier catch hook, or your own endpoint. The message is also in the `text` (Slack) and `content` (Discord) fields.

## `notifyWhenEmpty` (type: `boolean`):

By default the notification is sent only when at least one row was delivered.

## `requestIntervalMs` (type: `integer`):

Minimum pause between two page loads (and robots.txt reads) to the same site. Default 1000 ms. Pages on different sites are not delayed. Minimum 250.

## Actor input object example

```json
{
  "urls": [
    "https://example.com",
    "https://www.wikipedia.org",
    "https://developer.mozilla.org"
  ],
  "format": "png",
  "fullPage": true,
  "mobile": false,
  "deviceScaleFactor": 1,
  "quality": 80,
  "pdf": false,
  "delayMs": 0,
  "timeoutMs": 20000,
  "hideCookieBanners": true,
  "scrollToLoad": true,
  "maxItems": 0,
  "maxConcurrency": 2,
  "onlyNew": false,
  "stateName": "default",
  "notifyWhenEmpty": false,
  "requestIntervalMs": 1000
}
```

# Actor output Schema

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

One row per saved screenshot with its download link, size and timing, in the default dataset (JSON, CSV, Excel and other formats via the dataset API).

## `runSummary` (type: `string`):

Counts, average capture time, browser version, warnings and why the run stopped (RUN_SUMMARY record in the default key-value store).

## `coverage` (type: `string`):

One line per address you asked for: ok, blocked, robots_disallowed, not_found, timeout, error or not_checked, with the reason (COVERAGE record).

# 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://example.com",
        "https://www.wikipedia.org",
        "https://developer.mozilla.org"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("rowcraft/website-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 = { "urls": [
        "https://example.com",
        "https://www.wikipedia.org",
        "https://developer.mozilla.org",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("rowcraft/website-screenshot-api").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://example.com",
    "https://www.wikipedia.org",
    "https://developer.mozilla.org"
  ]
}' |
apify call rowcraft/website-screenshot-api --silent --output-dataset

```

## MCP server setup

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

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/6bJcgjaecmMlzpaCh/builds/Q0diG7MhCgl6mLcgO/openapi.json
