Website Screenshot API - Full Page Screenshot & URL to PDF avatar

Website Screenshot API - Full Page Screenshot & URL to PDF

Pricing

Pay per event

Go to Apify Store
Website Screenshot API - Full Page Screenshot & URL to PDF

Website Screenshot API - Full Page Screenshot & URL to PDF

Bulk website screenshots: full page screenshot, one element, mobile or tablet, several widths. URL to PDF (website to PDF) and clean Markdown in one run. Hides ads and cookie banners. Failures free.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Yukai Lin

Yukai Lin

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 hours ago

Last modified

Share

What does Website Screenshot API do?

Give it a list of URLs and get back, for every page:

  • ๐Ÿ“ธ Screenshot: viewport, full-page or one element only (e.g. a pricing table or chart), PNG / JPEG / WebP, desktop, laptop, tablet or mobile, retina (2x/3x) and dark mode
  • ๐Ÿ“„ PDF: print-ready A4 / Letter / Legal, portrait or landscape, with backgrounds
  • ๐Ÿ“ Markdown: clean, LLM-ready text of the page, without navigation, headers and footers by default, optionally limited to one part of it (e.g. article)

All three come from a single page load, so asking for several formats costs no extra waiting.

It also handles the things that usually break screenshots: lazy-loaded pages (scroll to the bottom first), pop-ups and chat widgets (hide any CSS selector), ads and trackers (blocked on request), slow widgets (wait for an element), and responsive checks (several devices or widths per URL in one run).

This Actor
Mobile and tablet emulation (touch, mobile layout, 2x/3x)โœ…
Several devices or widths per URL in one runโœ…
Scroll first to load lazy imagesโœ…
Hide elements by CSS selector, cookie banners removed automaticallyโœ…
Wait for a CSS selectorโœ…
Screenshot of one element (CSS selector)โœ…
Block ads and trackersโœ…
Retina and dark modeโœ…
PDF and Markdown from the same page loadโœ…
Failed or blocked pages freeโœ…
Start fee or extra compute chargeNone

Why use it?

  • You only pay for what works. If a site returns an error (403, 404, 500โ€ฆ), shows a bot-check page, or times out, you are not charged for that URL. The dataset tells you why it failed.
  • Clean captures. Cookie and consent banners are removed automatically, and so are sign-in walls, newsletter and discount pop-ups, push-notification prompts and the dark backdrop behind them (page scrolling is unlocked again). Both can be turned off.
  • Sticky headers only once. In full-page screenshots, fixed and sticky headers stay at the top, bottom bars and chat buttons move to the end of the page, so nothing repeats or covers the content.
  • Pages that never stop loading still get captured. Sites with endless trackers or live feeds are captured as soon as their content is there, instead of failing after a timeout.
  • Built for pipelines. Use it for monitoring, archiving, visual QA, link previews, compliance evidence, or feeding web pages to an LLM / RAG system. Call it from the API, a schedule, Make, Zapier, n8n or an AI agent.
  • Your spending limit is respected. The Actor reserves budget before starting each page and never does work your maximum charge cannot cover.

How much does it cost?

This Actor uses pay-per-event pricing. You are charged per successful output:

EventPrice
Screenshot$1.00 / 1,000
PDF$2.50 / 1,000
Markdown$2.00 / 1,000

Example: 1,000 URLs with a screenshot and a PDF of each cost 1,000 ร— $0.001 + 1,000 ร— $0.0025 = $3.50 on the Free plan.

No start fee. Failed, blocked and timed-out pages and invalid input lines are free. There is no charge for compute time on top of the event prices. On Apify's Scale plan prices are 10% lower, on Business and higher 20% lower (screenshot $0.80 / 1,000).

Total price compared with other screenshot Actors

What you pay per 1,000 screenshots on the Apify Store (checked September 2026). "Platform usage" means the Actor's compute time is billed to your Apify account on top of the listed price, so the total depends on the run:

ActorPrice per 1,000 screenshotsAlso billed to you
This Actor$1.00 (Business plan $0.80)Nothing: no start fee, compute included
cheapapi Website Screenshot API$0.89 (Business plan $0.61)Platform usage, $0.00001 start fee
crawlerbros Screenshot URL$2.00 (Business plan $1.00)Platform usage, $0.01 per run
moonweil URL Screenshot API$4.00$0.001 per run; one URL per run, so about $5 in bulk
i-scraper Website Screenshot$6.00Platform usage
dz_omar Screenshot$10.00 (Business plan $5.00)$0.05 start fee plus a memory charge
Apify Screenshot URLFree ActorPlatform usage only

cheapapi's listed price is lower than ours and it has more options (logins, proxies); compare the total on your own runs. We have no numbers for platform usage, so none are estimated here.

With several devices or widths, each screenshot is one event (3 widths = 3 screenshots). The PDF and the Markdown are made once per URL, with the first device, because they do not depend on the screen size.

Control your cost

  • What is charged: each output delivered (screenshot per device or width, PDF, Markdown). Every row has charged: true or false.
  • What is free: failed, blocked and timed-out pages, outputs that could not be produced, and invalid input lines.
  • At the start, the run logs its worst case, e.g. Plan: 50 URL(s) ร— 2 output(s) (screenshot, markdown) = at most $0.15, and warns when that is more than your maximum charge per run.
  • When the maximum charge per run is reached, the run stops and keeps everything captured so far. The status message says so, and the SUMMARY record has status: "LIMIT_REACHED" and notProcessed (how many URLs were not started, and up to 100 of them).

How to use it

  1. Paste your URLs into URLs, one per line (bare domains like example.com are fine).
  2. Pick the Outputs you want.
  3. Optionally tune screenshot, PDF, Markdown and loading options.
  4. Click Start. Results appear in the Output tab.

Input example

{
"urls": ["https://example.com", "www.python.org"],
"outputs": ["screenshot", "pdf", "markdown"],
"device": "mobile",
"fullPage": true,
"hideCookieBanners": true,
"screenshotFormat": "jpeg",
"screenshotQuality": 80
}

Responsive screenshots: phone, tablet width and desktop in one run

{
"urls": ["https://stripe.com"],
"devices": ["desktop", "mobile"],
"viewportWidths": ["768"],
"fullPage": true
}

Each URL gives one dataset item per variant, with a variant field (desktop, mobile, 768px) and its own screenshot.

Long pages with lazy-loaded images

{
"urls": ["https://stripe.com"],
"fullPage": true,
"scrollToBottom": true,
"scrollDelaySecs": 1,
"selectorsToHide": "header, .chat-widget",
"waitForSelector": "main"
}

Screenshot of one element, without ads

{
"urls": ["https://en.wikipedia.org/wiki/Cat", "https://example.com"],
"outputs": ["screenshot"],
"screenshotSelector": ".infobox",
"blockAds": true
}

Real output from this input (shortened). The Wikipedia item is a 283 ร— 1,088 px image of the infobox only. example.com has no .infobox, so it got a normal screenshot and selectorNotFound: true. Both count as one screenshot each:

[
{ "url": "https://en.wikipedia.org/wiki/Cat", "success": true, "screenshotSelector": ".infobox", "selectorNotFound": false, "screenshotBytes": 260403, "screenshotUrl": "https://api.apify.com/v2/key-value-stores/โ€ฆ/records/00000-en-wikipedia-org-wiki-Cat-screenshot.png" },
{ "url": "https://example.com", "success": true, "screenshotSelector": ".infobox", "selectorNotFound": true, "screenshotBytes": 23439, "screenshotUrl": "https://api.apify.com/v2/key-value-stores/โ€ฆ/records/00001-example-com-screenshot.png" }
]

Output example

Each URL produces one dataset item. Screenshots and PDFs are stored in the run's key-value store and linked by URL:

{
"url": "https://stripe.com",
"finalUrl": "https://stripe.com/",
"httpStatus": 200,
"title": "Stripe | Financial Infrastructure to Grow Your Revenue",
"success": true,
"inputIndex": 0,
"inputUrl": "stripe.com",
"variant": "mobile",
"device": "mobile",
"viewportWidth": 390,
"viewportHeight": 844,
"pixelDensity": 3,
"screenshotUrl": "https://api.apify.com/v2/key-value-stores/โ€ฆ/records/00000-stripe-com-screenshot-mobile.jpg",
"screenshotBytes": 1255663,
"screenshotTruncated": true,
"format": "jpeg",
"fullPage": true,
"pdfUrl": null,
"markdown": null,
"scrolledPx": 16880,
"hiddenElements": 5,
"waitForSelectorTimedOut": true,
"errors": {},
"loadTimedOut": false,
"cookieBannersHidden": 0,
"capturedAt": "2026-09-29T02:01:42.003Z",
"charged": true
}

Field notes:

  • inputIndex is the URL's position in your list (from 0) and inputUrl the line exactly as you entered it. Pages finish in parallel, so sort by inputIndex to get your original order.
  • variant appears only when you use several devices or several widths.
  • screenshotBytes / pdfBytes are file sizes; scrolledPx is how far the page was scrolled; hiddenElements counts elements hidden by your selectors.
  • waitForSelectorTimedOut: true means the element never appeared (this test waited for a selector that does not exist); the page was still captured.
  • screenshotTruncated: true means the full page was longer than 16,384 px (or your Max full-page height) and was cut there. Set maxScreenshotHeight (e.g. 3000) when you only want a preview of the top of long pages.
  • screenshotSelector and selectorNotFound appear only when you set Screenshot only this element.

A page the site refused looks like this and is not charged:

{ "url": "https://example.com/private", "inputIndex": 3, "inputUrl": "example.com/private", "success": false, "error": "target returned HTTP 403 (not charged)", "errorType": "blocked", "charged": false, "httpStatus": 403 }

errorType is one of blocked, not_found, timeout, network, http_error, too_large, unsupported, invalid_input or failed. The run's key-value store also has a SUMMARY record with status (SUCCESS, PARTIAL_RESULTS, FAILED, NO_RESULTS or LIMIT_REACHED) counts, and failedUrls (up to 100).

Tips

  • Faster runs: set Wait until to load. networkidle2 (default) waits for most network activity to finish, which gives more complete pages but takes longer.
  • Lazy-loaded images: turn on Scroll to the bottom first (and keep a 1-second wait after scrolling).
  • A pop-up or chat bubble is still there: list its CSS selector in Hide these elements (the automatic pop-up detection is conservative: it never hides site headers, hero sections or page content).
  • Charts or widgets that render late: set Wait for this element to their selector.
  • Faster, lighter Markdown: under Don't load these resources, skip images and fonts.
  • No ads or tracking scripts: turn on Block ads and trackers (Advanced settings). It stops about 50 common ad and analytics hosts from loading.
  • Only a pricing table, chart or product box: set Screenshot only this element to its CSS selector. Sticky banners that float over the element are captured too, so also list them in Hide these elements.
  • Mobile screenshots: set Device to Mobile for a real mobile layout at 3x density.
  • Sharper desktop images: set Pixel density to 2.
  • Dark theme: turn on Dark mode (works on sites that support it).
  • Keep the cookie banner (e.g. for compliance evidence): turn off Hide cookie banners.
  • Only the article text: set the Markdown CSS selector to article or main. Navigation, headers and footers are already removed from the Markdown by default (Remove navigation, headers and footers): when the page has one main content element (article, main) only that element is converted, and leftover skip links, empty headings and image placeholders are tidied away; add more selectors under Also remove these elements from the Markdown, or turn the option off ("markdownRemoveBoilerplate": false) to convert the whole page. In our test the Markdown of github.com went from about 66,000 to 9,849 characters.
  • Calling the API or n8n? Use the plain urls list. The older startUrls field still works, but Apify rejects the whole run (HTTP 400) when it holds a bare domain or a blank line.
  • Screenshots of a whole website: get its page list with Sitemap URL Extractor, then pass the url values as urls here.
  • Only need Markdown for many pages or a whole site? Website to Markdown Crawler fetches pages over plain HTTP for $1 per 1,000 pages (set Crawl scope to Only the start URLs for a URL list).

Use with AI agents (MCP)

Connect Apify's MCP server (https://mcp.apify.com?tools=tidytools/website-screenshot-pdf-markdown) to Claude, Cursor or any MCP client, then ask e.g. "Take full-page desktop and mobile screenshots of stripe.com and give me the image links."

Minimal input:

{ "urls": ["https://stripe.com"], "outputs": ["screenshot"] }

Failed items are not charged and carry an errorType. Each item links its screenshot (screenshotUrl) and PDF (pdfUrl); Markdown is inline in markdown.

Use it from code and integrations

Run it from your own code with the Apify API. This call waits for the run and returns the results as JSON (replace YOUR_TOKEN with your Apify API token):

curl -X POST "https://api.apify.com/v2/acts/tidytools~website-screenshot-pdf-markdown/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"urls":["https://example.com"],"outputs":["screenshot","markdown"]}'

The synchronous endpoint waits up to 5 minutes. For bigger runs, start the run with POST https://api.apify.com/v2/acts/tidytools~website-screenshot-pdf-markdown/runs and read the dataset when it finishes, or use the apify-client package for JavaScript or Python.

Schedules and integrations: run it daily or weekly with Apify Schedules, get a webhook when a run finishes, or send the results to Zapier, Make, n8n, Google Sheets, Slack and other apps with Apify integrations. Results can be exported as JSON, CSV, Excel or XML.

Limitations

  • Only public http/https pages. Pages behind a login, private networks and local addresses are not supported.
  • Some sites actively block automated browsers. Those URLs are reported as failed and are not charged.
  • Full-page screenshots are cut at 16,384 px height.
  • Pages are rendered on our own servers, so Apify proxies cannot be used for this Actor.
  • Captures are rendered by a headless Chromium browser, so a few sites may look slightly different than in your own browser.

Capturing publicly available pages is generally allowed, but you are responsible for how you use the output. Respect each site's terms of service, copyright and privacy laws, and don't use the results to collect personal data without a legal basis.

FAQ

Can I take full-page screenshots of many URLs at once? Yes. Paste the URLs one per line (bare domains are fine) and turn on Full page. Long pages are cut at 16,384 px (or your Max full-page height); turn on Scroll to the bottom first so lazy-loaded images appear.

How do I convert a URL to PDF? Pick PDF under Outputs: A4, Letter or Legal, portrait or landscape, with backgrounds, for $2.50 per 1,000 PDFs. The PDF, screenshot and Markdown come from the same page load.

Can I get mobile and tablet screenshots? Yes. Set Device to Mobile for a real mobile layout at 3x density, or list several devices or widths (devices, viewportWidths) to get each variant in one run. Each variant is one screenshot.

Can I use it as a screenshot API from my code? Yes. Call the run-sync-get-dataset-items endpoint shown above, use the apify-client package, or connect it to an AI agent through Apify's MCP server. Failed pages are not charged.

Support

Found a page that doesn't render correctly or need a feature? Open an issue in the Issues tab with the URL and your input settings.