Website Screenshot & PDF API: Full Page, Mobile, Cookie-Free avatar

Website Screenshot & PDF API: Full Page, Mobile, Cookie-Free

Pricing

Pay per event

Go to Apify Store
Website Screenshot & PDF API: Full Page, Mobile, Cookie-Free

Website Screenshot & PDF API: Full Page, Mobile, Cookie-Free

Full-page or viewport screenshots (PNG, JPEG, WebP) and PDFs of any URL on desktop, tablet or mobile. Rejects cookie banners, blocks ads, waits for selectors or network idle, dark mode, element capture, custom CSS/JS. Public file URLs. $2 per 1,000 screenshots; failures are free.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Tidewell Software

Tidewell Software

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

13 hours ago

Last modified

Categories

Security

Limited permissions

Share

Website Screenshot & PDF API: full page, mobile, no cookie banners

Capture full-page or above-the-fold screenshots (PNG, JPEG, WebP) and PDFs of any URL, on desktop, laptop, tablet, iPhone or Android, in real Chromium. Every file is saved to the run's key-value store, and you get a public URL for it in the dataset, along with the page title, final URL, HTTP status, pixel size, file size and timings.

  • Clean captures. Cookie banners are rejected ("Reject all" / "Only necessary") on 25+ consent platforms and in 14 languages, or hidden when there is no reject button. "Accept all" is never clicked. Optional ad and tracker blocking, and a list of your own elements to hide.
  • Complete full-page shots. The page is scrolled first so lazy-loaded images appear, animations are frozen at a sensible frame, and carousels don't come out blank.
  • Wait the way you need. Load event, DOM ready or network idle, wait for a CSS selector, plus an extra delay.
  • Every device. Desktop 1920x1080, laptop 1366x768, iPad, iPhone and Pixel presets (2x retina), or any custom viewport and pixel ratio. Capture each URL on several devices in one run.
  • PDFs that look like the page. A4, Letter, Legal, A3, A5, Tabloid or one long single page, with margins, landscape, scale, background graphics and screen or print CSS.
  • More control. Dark mode (prefers-color-scheme: dark), element-only screenshots by selector, custom CSS and JavaScript injection, custom user agent, HTML to image / HTML to PDF.
  • Pay per file. $2 per 1,000 screenshots, $3 per 1,000 PDFs, plus $0.001 per run. Failed pages (DNS errors, timeouts, HTTP 404/500, missing selectors) are free, and so are retries.

What can you use it for?

Use caseHow
Website monitoring and visual change trackingSchedule a run with your URLs and compare today's PNGs with yesterday's
SEO and client reportsCapture landing pages on desktop and mobile in one run (devices: ["desktop", "mobile"])
Archiving and compliance evidenceFull-page PDFs or PNGs saved to a named key-value store that keeps every capture
Social cards, thumbnails and link previewsViewport JPEG or WebP at quality 70-80, or an element-only shot of a #hero section
Invoices, receipts and certificates from HTMLPass html and render it to PDF or PNG
QA and responsive design checksOne URL x five devices, dark mode on and off
AI agents and automationsCall it from Make, Zapier, n8n, LangChain or Apify's MCP server and pass the fileUrl to a vision model

How to use it

  1. Paste your URLs, one per line.
  2. Choose one or more devices, and an output format (PNG, JPEG, WebP or PDF).
  3. Leave Full page on to capture the whole page, or turn it off for the visible viewport only.
  4. Click Start. Each capture appears in the Output tab with a preview, and the dataset can be downloaded as JSON, CSV or Excel, or read with the Apify API.

Input example: desktop and mobile full-page PNGs

{
"urls": ["https://apify.com", "https://en.wikipedia.org/wiki/Web_scraping"],
"devices": ["desktop", "mobile"]
}

Input example: above-the-fold JPEG thumbnails with ads blocked

{
"urls": ["https://www.theguardian.com/uk", "https://www.lemonde.fr"],
"fullPage": false,
"format": "jpeg",
"quality": 75,
"blockAds": true,
"waitUntil": "networkidle"
}

Input example: one element only, at 2x, in dark mode

{
"urls": ["https://en.wikipedia.org/wiki/Python_(programming_language)"],
"selector": ".infobox",
"deviceScaleFactor": 2,
"darkMode": true,
"hideSelectors": [".infobox-image"]
}

Input example: URL to PDF (A4, 10 mm margins) and one long single-page PDF

{ "urls": ["https://apify.com/pricing"], "format": "pdf", "pdfFormat": "A4", "pdfMargin": "10mm" }
{ "urls": ["https://apify.com"], "format": "pdf", "pdfFormat": "single-page" }

Input example: HTML to image

{
"html": "<html><body style='font-family:sans-serif;padding:60px'><h1>Invoice #1042</h1></body></html>",
"devices": ["custom"],
"viewportWidth": 800,
"viewportHeight": 400,
"fullPage": false
}

Input fields

FieldWhat it does
urlsPages to capture. https:// is added when missing, and duplicates are removed
devicesAny of desktop (1920x1080), laptop (1366x768), tablet (iPad, 820x1180 @2x), mobile (iPhone, 393x852 @2x), android (Pixel, 412x915 @2x), custom. Each URL is captured once per device
formatpng (default), jpeg, webp or pdf
fullPagetrue (default) for the whole page, false for the viewport only
quality1-100 for JPEG and WebP (default 80)
selectorCapture only the first visible element matching this CSS selector
htmlRaw HTML to render as an extra capture
viewportWidth, viewportHeightSize of the custom device; on desktop and laptop they override the preset
deviceScaleFactorPixel ratio, 0.5-4 (2 = retina)
maxHeightFull-page screenshots of endless pages are cut at this height in CSS pixels (default 20,000)
waitUntilload (default), networkidle (capped at 20 s, then captured anyway) or domcontentloaded
waitForSelectorWait until this element is visible. If it never appears, the capture fails and is free
delayMsExtra wait just before the capture (default 500)
scrollToLoadLazyContentScroll through the page first so lazy images load (default on)
navigationTimeoutSecsPage-load limit (default 45). A page that is usable when time runs out is still captured, with a warning
dismissCookieBannersReject or hide cookie banners (default on)
hideSelectorsYour own elements to remove, e.g. #chat-widget
blockAdsBlock about 150 ad, analytics and tracking networks and collapse ad slots
darkModeEmulate prefers-color-scheme: dark
disableAnimationsFreeze CSS animations and transitions (default on)
customCss, customJsInjected before the capture. JavaScript runs as the body of an async function, so await works
userAgentOverride the device's user agent
pdfFormatA4 (default), Letter, Legal, A3, A5, Tabloid, single-page
pdfLandscape, pdfMargin, pdfPrintBackground, pdfMediaType, pdfScalePDF layout. Margin takes a unit: 10mm, 0.5in, 1cm, 20px
captureErrorPagesAlso capture (and pay for) pages that answer HTTP 4xx/5xx. Off by default
maxConcurrencyPages captured in parallel (default 4, also limited by memory)
maxRetriesRetries for timeouts, connection errors and HTTP 429/5xx (default 1). Retries are free
keyValueStoreNameSave files to a named key-value store that outlives the run's data retention
proxyConfigurationOptional Apify Proxy, for example to see a page as visitors in another country do

Output

One dataset row per URL and device:

{
"url": "https://apify.com",
"source": "url",
"status": "succeeded",
"finalUrl": "https://apify.com/",
"httpStatus": 200,
"title": "Apify: Marketplace of ready-to-run tools for AI",
"device": "desktop",
"viewport": "1920x1080",
"deviceScaleFactor": 1,
"format": "png",
"fullPage": true,
"fileKey": "apify.com-desktop-2a0632.png",
"fileUrl": "https://api.apify.com/v2/key-value-stores/Dc5rB5jXL8A0nSMdK/records/apify.com-desktop-2a0632.png?signature=...",
"contentType": "image/png",
"width": 1920,
"height": 10036,
"bytes": 1199072,
"pdfPages": null,
"cookieBanner": {"action": "hidden", "platform": null, "hiddenElements": 3, "hidden": ["div#onetrust-consent-sdk", "div#onetrust-banner-sdk.otFloatingRoundedCorner.ot-bottom-left", "div.onetrust-pc-dark-filter.ot-hide"]},
"blockedRequests": null,
"timings": {"navigationMs": 1322, "waitMs": 0, "prepareMs": 3954, "captureMs": 810, "browserMs": 6172, "saveMs": 157, "totalMs": 6338},
"totalMs": 6338,
"attempts": 1,
"warnings": [],
"error": null,
"errorCode": null,
"charged": true,
"capturedAt": "2026-11-08T03:54:02Z"
}
FieldNotes
fileUrlPublic link to the file. It works without an API token, in a browser, <img> tag or vision model
width, heightImage size in pixels: CSS size x pixel ratio, so an iPhone capture is 786 px wide
pdfPagesNumber of pages in a PDF
cookieBanner.actionrejected (a reject / necessary-only button was clicked), hidden (no reject button, so the banner was hidden) or none
httpStatusStatus of the main document. 4xx and 5xx count as failed unless captureErrorPages is on
errorCodedns_error, connection_error, navigation_timeout, http_404, http_403, wait_selector_not_found, selector_not_found, invalid_url, ...
warningsThings that didn't stop the capture: page cut at maxHeight, network never idle, a customJs error, ...
chargedWhether this row was billed. Failed rows are never billed

The dataset has four views: Overview (with image previews), Files & links, Details (cookie banner, blocked requests, timings) and Status & errors. The files are in the run's key-value store, and the record RUN_SUMMARY lists every capture's status, including any skipped because the run hit its maximum cost.

Pricing

Pay per event. You pay only for files that were saved:

EventPriceWhen
Screenshot$0.002Once per PNG, JPEG or WebP file saved
PDF$0.003Once per PDF saved
Run start$0.001 per run$0.0005 per GB of memory, so $0.001 at the default 2 GB. It pays for starting the browser, so single-page API calls stay possible at this price

Everything else is included: there's no charge for compute time, retries, failed pages, cookie handling, ad blocking or the dataset rows. Set Max cost per run in the run options to cap spending. The Actor reserves the price before each capture, so it stops cleanly before a page it couldn't pay for and lists the rest as skipped in RUN_SUMMARY.

Examples:

  • 1 URL on desktop and mobile: $0.005 ($0.001 start + 2 screenshots)
  • 1,000 product pages in one run, one full-page PNG each: $2.001
  • 50 client landing pages on 3 devices, one run a week for 4 weeks: 600 screenshots, $1.204
  • One single-URL API call: $0.003

Tips

  • Very long pages. Full-page captures are cut at maxHeight (20,000 CSS px by default) so endless feeds don't produce giant files. Raise it up to 60,000 if you need more. WebP can't exceed 16,383 px per side, so taller WebP captures are scaled down to fit (with a warning). Use PNG or JPEG for full resolution.
  • Charts and single-page apps. Use waitUntil: "networkidle" or waitForSelector for the element that appears last, plus a delayMs of 1000-2000.
  • Sticky headers in full-page shots. Add header { position: static !important; } to customCss.
  • Clicking a tab before the capture. Use customJs, e.g. document.querySelector('#tab-pricing').click(); await new Promise(r => setTimeout(r, 500));
  • Big batches. Each page needs about 512 MB, so raise the run's memory (4-8 GB) and maxConcurrency for thousands of URLs. The price per file doesn't change.
  • Keep files longer. Unnamed run storage follows your plan's data retention. Set keyValueStoreName (e.g. site-archive) to keep captures indefinitely.

Other actors from Tidewell

FAQ

How does the cookie banner handling work? After the page loads, the Actor looks for a "Reject all" or "Only necessary" button from known consent platforms (OneTrust, Cookiebot, Didomi, Quantcast, Usercentrics, Google Funding Choices, Sourcepoint, TrustArc, CookieYes, Complianz, Osano, iubenda, Klaro, Axeptio, consentmanager, Ketch, Borlabs, HubSpot, Termly, Shopify and others), including inside shadow DOM and consent iframes. It then looks for buttons with that wording in 14 languages. If there's no such button, the banner is hidden with CSS instead, and scrolling is unlocked. It never clicks "Accept all". It's best effort: an unusual banner can still slip through, and in that case you can add its selector to hideSelectors. The cookieBanner field in each row says what happened.

Why did a page fail with http_403? Some sites block automated browsers or data-centre traffic. Those captures fail, and you are not charged. If you're allowed to capture the page, routing through Apify Proxy (proxyConfiguration) can help when a site blocks data-centre IP ranges. Turn on captureErrorPages if you want a picture of the error page itself.

Is it legal to screenshot websites? Capturing a public page is generally fine for monitoring, QA, archiving and reporting. What you do with the image matters: copyright, trademarks and personal data shown on the page still belong to their owners, and some sites' terms restrict automated access. You're responsible for checking that your use complies with the law and the site's terms. This isn't legal advice.

Can I capture pages behind a login? Not directly. You can pass session cookies by setting them with customJs (document.cookie = ...) and a reload, but only for accounts you own and are allowed to automate.

Does dark mode work on every site? It sets prefers-color-scheme: dark, the same signal a phone in dark mode sends. Sites with a dark theme switch to it, and sites without one don't change.

Why is the iPhone screenshot 786 px wide? The iPhone preset renders a 393 CSS px wide viewport at a 2x pixel ratio, so text is retina-sharp without huge files. Set deviceScaleFactor: 3 for the exact pixels of a real iPhone 15 (1179 px), or 1 for a 393 px image.

Can I schedule it? Yes. Use Apify Schedules, then send the dataset to Google Sheets, Slack, a webhook, Make or Zapier, or read the files from a named key-value store.

Something looks wrong? Open an issue on the Actor's Issues tab with the run ID and the URL. Rendering fixes are shipped quickly.

Keywords

website screenshot, screenshot api, full page screenshot, url to pdf, html to pdf, html to image, webpage to png, url to image, mobile screenshot, responsive screenshot, website thumbnail, page capture, web archive, visual monitoring, cookie banner remover, playwright screenshot, chromium screenshot, puppeteer screenshot alternative