Website Screenshot API, Full Page & URL/HTML to PDF
Pricing
from $2.00 / 1,000 files
Website Screenshot API, Full Page & URL/HTML to PDF
Website screenshot API and URL/HTML to PDF converter. Full-page PNG, JPEG, WebP and A4/Letter PDF from one page load. Batch from a URL list, sitemap or dataset; iPhone/Android views; cookie banners hidden; visual regression diff. $2 per 1,000 files, failed URLs free.
Pricing
from $2.00 / 1,000 files
Rating
0.0
(0)
Developer
Rigel
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
17 hours ago
Last modified
Categories
Share
Take a website screenshot (viewport, full page, one element, or a mobile view) and convert URLs or raw HTML to PDF, in bulk, from one Apify Actor. Each page is loaded once in headless Chromium, then every format you ask for (PNG, JPEG, WebP, PDF) comes from that same load. You pay $0.002 per stored file. Failed, blocked and skipped URLs are free.
- Full-page screenshots up to 16,384 px tall, with lazy images scrolled into view.
- Mobile and tablet views: iPhone 15, Pixel 8, iPad, plus desktop, laptop, MacBook Retina and a 1200×630 Open Graph card.
- URL to PDF and HTML to PDF: A4, Letter, Legal or A3, margins, landscape, backgrounds, page numbers, custom header and footer.
- Batch input: a list of URLs, a
sitemap.xml(indexes and.xml.gzfollowed), or the URLs of an existing dataset. Up to 5,000 URLs per run. - Visual regression diff: compare each screenshot with the previous run and get
percentChangedplus a diff image. - Clean captures: common cookie banners hidden with CSS, ads and trackers blocked, dark mode, custom CSS, hide or blur selectors.
- API-first: REST, Python, JavaScript, sync endpoint that returns the file bytes, MCP for AI agents, n8n and Make.
Social networks and private network addresses are refused before any navigation (see Legal and safety).
Use cases
| You want to… | Use these inputs |
|---|---|
| Archive how a page looked, as an image and a PDF | formats: ["png", "pdf"], fullPage: true |
| Check a responsive layout on a phone | device: "iphone_15" or "pixel_8" |
| Turn a list of documentation or report pages into PDFs | urls: [...], formats: ["pdf"], pdf.format: "A4" |
| Generate PDF invoices, receipts or reports from your own HTML | html: "<html>…", formats: ["pdf"] |
| Get alerted when a page changes visually (visual regression testing) | compareWithPrevious: true + an Apify schedule |
| Make thumbnails of every page of your site | sitemapUrl, formats: ["jpeg"], quality: 75 |
| Capture a single chart, pricing table or widget | selector: ".pricing-table" |
| Create link-preview / Open Graph images | device: "og_card" (1200×630) |
Ready-made examples: Full-page PNG · iPhone view · Bulk URL to A4 PDF · HTML invoice to PDF · Visual regression diff · Element screenshot · Sitemap thumbnails · Open Graph image
Pricing
Pay per event. Compute is included: there is no separate charge for CPU or memory.
| Event | Price | When |
|---|---|---|
| Actor start | $0.0005 per GB of run memory | Once per run. At the default 2 GB this is $0.001; at the 1 GB minimum, $0.0005. |
| File | $0.002 | One PNG, JPEG, WebP or PDF stored. PNG + PDF of the same page = 2 files. |
| Visual diff | $0.001 | Only when a baseline already existed and a diff was computed. The first run, which creates the baseline, is not charged for a diff. |
Not charged: invalid URLs, blocked domains, private addresses, DNS or connection errors, HTTP 4xx/5xx (unless you turn on captureErrorPages), timeouts, missing selectors, non-HTML responses (PDF or ZIP downloads), duplicates, and URLs skipped after your spending limit is reached.
What a run costs (default 2 GB memory)
| Run | Files | Cost |
|---|---|---|
| 1 URL, one PNG | 1 | $0.003 |
| 1 URL, PNG + PDF | 2 | $0.005 |
| One raw HTML invoice to PDF | 1 | $0.003 |
| 100 URLs, full-page PNG | 100 | $0.201 |
| 1,000 URLs to PDF | 1,000 | $2.001 |
| 1,000 URLs, PNG + PDF | 2,000 | $4.001 |
| 50 URLs checked daily with visual diff (after the first run) | 50 + 50 diffs | $0.151 per run, about $4.53 per month |
Set a maximum cost per run in Apify Console or with maxTotalChargeUsd in the API: when it is reached, the remaining URLs are returned as skipped and not charged.
Input examples
All field names below are the real input fields of this Actor. Only one source is required: urls, html, sitemapUrl or datasetId.
Full-page screenshot, desktop
{"urls": [{ "url": "https://en.wikipedia.org/wiki/Screenshot" }],"formats": ["png"],"fullPage": true,"device": "desktop"}
Mobile screenshot (iPhone 15, 393×852 at 3×)
{"urls": [{ "url": "https://www.wikipedia.org/" }],"formats": ["png"],"device": "iphone_15"}
Bulk URL to PDF, A4 with page numbers
{"urls": [{ "url": "https://example.com/" },{ "url": "https://en.wikipedia.org/wiki/PDF" },{ "url": "https://docs.apify.com/platform/actors" }],"formats": ["pdf"],"pdf": {"format": "A4","landscape": false,"printBackground": true,"pageNumbers": true,"margin": { "top": "1cm", "right": "1cm", "bottom": "1.4cm", "left": "1cm" }}}
HTML to PDF (your own HTML, up to 2 MB)
{"html": "<!doctype html><html><body><h1>Invoice INV-001</h1><p>Total: $2.50</p></body></html>","formats": ["pdf"],"pdf": { "format": "Letter", "pageNumbers": true }}
Visual regression: diff against the previous run
{"urls": [{ "url": "https://example.com/" }],"formats": ["png"],"compareWithPrevious": true,"baselineStoreName": "rigel-screenshot-baselines","diffThreshold": 0.1}
Screenshots of a whole site from its sitemap
{"sitemapUrl": "https://docs.apify.com/sitemap.xml","maxUrls": 50,"formats": ["jpeg"],"quality": 75,"device": "laptop"}
One element only, at 2× density
{"urls": [{ "url": "https://en.wikipedia.org/wiki/Portable_Network_Graphics" }],"formats": ["png"],"selector": ".infobox","deviceScaleFactor": 2}
Other useful fields: width / height / deviceScaleFactor to override a device, clip ({x, y, width, height}), omitBackground (transparent PNG/WebP), waitUntil (load, domcontentloaded, networkidle), waitForSelector, delayMs, scrollToLoad, timeoutSecs (per page, 5–90 s), darkMode, hideCookieBanners, acceptCookies, blockAds, hideSelectors, blurSelectors, customCss, maxConcurrency (1–8), datasetId + urlField.
Output
Files go to the run's default key-value store. Key format: <host>-<10-char hash of URL and options>.<ext> (raw HTML: html-<hash>.<ext>). OUTPUT holds a copy of the first stored file and RUN_SUMMARY.json has counts, events and duration.
The dataset has one row per URL:
{"url": "https://example.com/","finalUrl": "https://example.com/","status": "ok","errorCode": null,"httpStatus": 200,"files": [{"format": "png","key": "example.com-0b5df33ae2.png","url": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/example.com-0b5df33ae2.png?signature=…","bytes": 78288,"width": 1920,"height": 1080,"truncated": false}],"page": { "title": "Example Domain", "lang": "en", "loadMs": 119, "consoleErrors": 0 },"visualDiff": { "baselineFound": true, "percentChanged": 0, "changedPixels": 0, "diffKey": "diff-example.com-0b5df33ae2.png" },"charged": { "capture": 1, "visual-diff": 1 }}
files[].url is a signed link that opens without your API token. PDFs have pages instead of width/height. status is ok, failed, blocked or skipped, with a stable errorCode (for example NAVIGATION_TIMEOUT, HTTP_ERROR, SELECTOR_NOT_FOUND, BLOCKED_DOMAIN). visualDiff is null unless compareWithPrevious is on. The dataset has two views: Overview and Errors.
Use it from the API
Get your token in Apify Console › Settings › API & Integrations.
cURL: get the file bytes in one call (sync endpoint, returns the OUTPUT record)
curl -X POST "https://api.apify.com/v2/acts/rigel~website-screenshot-pdf/run-sync-get-output" \-H "Authorization: Bearer $APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"urls":[{"url":"https://example.com"}],"formats":["pdf"],"pdf":{"format":"A4","pageNumbers":true}}' \--output page.pdf
Python (pip install "apify-client>=3")
import osimport requestsfrom apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("rigel/website-screenshot-pdf").call(run_input={"urls": [{"url": "https://example.com"}, {"url": "https://en.wikipedia.org/wiki/PDF"}],"formats": ["png", "pdf"],"fullPage": True,})for row in client.dataset(run.default_dataset_id).iterate_items():for f in row.get("files", []):with open(f["key"], "wb") as out:out.write(requests.get(f["url"], timeout=60).content)print(row["status"], f["key"], f["bytes"])
JavaScript / Node.js (npm install apify-client)
import { ApifyClient } from 'apify-client';import { writeFile } from 'node:fs/promises';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('rigel/website-screenshot-pdf').call({urls: [{ url: 'https://example.com' }],formats: ['png'],device: 'iphone_15',});const { items } = await client.dataset(run.defaultDatasetId).listItems();for (const row of items) {for (const f of row.files ?? []) {const res = await fetch(f.url);await writeFile(f.key, Buffer.from(await res.arrayBuffer()));console.log(row.status, f.key, f.bytes);}}
Use it from AI agents (MCP)
Add the Apify MCP server with only this Actor as a tool:
{ "mcpServers": { "website-screenshot": { "url": "https://mcp.apify.com?tools=rigel/website-screenshot-pdf" } } }
or claude mcp add --transport http website-screenshot "https://mcp.apify.com?tools=rigel/website-screenshot-pdf". Sign in with OAuth or send Authorization: Bearer <APIFY_TOKEN>. The agent passes the same input as above and reads files[].url from the result.
n8n and Make
- n8n: Apify node › Run an Actor (
rigel/website-screenshot-pdf, wait for finish) › Apify node › Get dataset items › HTTP Request onfiles[0].urlto download the PNG or PDF. For visual regression, add an IF node onvisualDiff.percentChanged > 1and send yourself an email or a Slack message. - Make: Apify app › Run an Actor (synchronous) › Get Dataset Items › HTTP › Get a file on
files[].url. - Schedules: an Apify schedule on a saved task with
compareWithPrevious: truegives you a daily visual check without n8n or Make.
Keep cookies, headers and proxyUrl out of logged steps: they are secret inputs.
Related Actors
- PDF to Markdown for RAG & LLMs: when a URL is a PDF, DOCX or other file (
NOT_A_WEB_PAGE, not charged here), send it there to get Markdown or RAG chunks with page numbers.
FAQ
Do I pay for URLs that fail? No. Only stored files and computed diffs are charged, plus the start event of the run.
Can I take a full-page screenshot of a very long page? Yes, up to 16,384 device pixels tall. Longer pages are cut and the file is flagged truncated: true. Lazy images are scrolled into view first for full-page captures.
How do I convert HTML to PDF without hosting it? Put the HTML string in html and set formats: ["pdf"]. CSS, web fonts and images referenced by public URLs are rendered. One HTML document per run.
How does the visual diff work? With compareWithPrevious: true, the PNG of each URL is compared pixel by pixel (pixelmatch) with the baseline stored by the previous run in the named key-value store baselineStoreName of your account, then the baseline is replaced. The diff image key is in visualDiff.diffKey. Changing the device or capture options creates a new baseline.
Can it capture pages behind a login? You can pass cookies and headers for your own site. They are sent only to the target origin, never to third parties or after a redirect to another origin, and never logged. You must have the right to access and capture the page.
Can I use a proxy? Yes, your own http or socks5 proxy in proxyUrl. Apify Proxy is not used.
How fast is it? Pages run in parallel: 2 at the default 2 GB, 3 at 4 GB, or set maxConcurrency (1–8). A simple page takes about 1 second of browser time.
How long are the files kept? They live in the run's key-value store, which follows the data retention of your Apify plan. Download them or copy them to your own storage if you need them longer.
Why was my URL refused? Social and profile platforms (Facebook, Instagram, LinkedIn, TikTok, X, Reddit and others) are blocked, as well as private and loopback addresses. File downloads such as PDF links return NOT_A_WEB_PAGE, free of charge. To convert documents to text, use rigel/doc-to-markdown.
Zapier: my Zap times out. Zapier's synchronous "Run Actor" action stops waiting after 30 seconds. For batches, run the Actor asynchronously and start the next step from Apify's "Finished Actor run" trigger, then read the results with the "Fetch dataset items" search.
Limits
- 5,000 URLs per run (
maxUrls), 2 MB of raw HTML, 8 KB of custom CSS. - Per-page timeout 5–90 seconds (default 30).
- Full-page height capped at 16,384 device pixels.
- A browser crash is retried once, then returned as
BROWSER_CRASH, free of charge.
Legal and safety
You need the right to capture each page; the Actor does not decide that for you. It does not collect accounts, profiles or personal data, and it does not log page content, cookies or request headers. Social and profile platforms are blocked in code. Loopback, private (RFC 1918), link-local (including cloud metadata), CGNAT and IPv6 unique-local addresses are rejected for the page, its redirects and its subresources.
Support
Open an issue on the Issues tab. Bug reports with the run ID get the fastest answer.