snaplab Screenshot & PDF Renderer avatar

snaplab Screenshot & PDF Renderer

Pricing

Pay per usage

Go to Apify Store
snaplab Screenshot & PDF Renderer

snaplab Screenshot & PDF Renderer

Render any URL or raw HTML to a PNG/JPEG/WebP screenshot or a PDF, with ad blocking, cookie-banner removal, dark mode and full-page capture.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

Harpreet Singh

Harpreet Singh

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 hours ago

Last modified

Categories

Share

Point this actor at a list of URLs (or a blob of raw HTML) and get back clean PNG, JPEG, WebP or PDF files — no ad clutter, no cookie banners, no half-loaded pages. It runs a real headless chromium on the Apify platform, so what you get is what a browser sees, at whatever viewport, colour scheme and page length you ask for. Every render lands in the run's key-value store with a direct link in the dataset row next to it.

What it does

  • Renders any URL or raw HTML to PNG, JPEG, WebP or PDF.
  • Full-page capture — the whole scrollable document, not just the fold.
  • Ad & tracker blocking — requests to known ad, analytics and session-replay hosts are aborted before they load.
  • Cookie-banner removal — common consent dialogs are hidden, and an obvious accept button is clicked when one is present.
  • Dark mode — emulates prefers-color-scheme: dark.
  • Custom viewport — width and height from 320×240 up to 4096×4096.
  • Render delay — wait up to 10 seconds after load for animations and lazy-loaded content.
  • Files land in the key-value store, with a direct link (keyValueStoreUrl) in each dataset row.

Input

{
"urls": [{ "url": "https://news.ycombinator.com" }, { "url": "https://example.com" }],
"mode": "screenshot",
"format": "png",
"fullPage": true,
"width": 1280,
"height": 800,
"darkMode": false,
"blockAds": true,
"blockCookieBanners": true,
"delay": 500
}

Leave urls empty and pass html instead to render a string of markup. Pass both and you get one render per URL plus one for the HTML.

Output

One dataset row per target:

{
"url": "https://news.ycombinator.com",
"kind": "screenshot",
"keyValueStoreUrl": "https://api.apify.com/v2/key-value-stores/aBcDeFgHiJkLmNoPq/records/render-0-1757210000000.png",
"width": 1280,
"height": 800,
"bytes": 412870,
"tookMs": 2841
}

The binary file itself is not in the dataset — it lives in the run's key-value store at the keyValueStoreUrl shown in the row. Fetch that URL to download the image or PDF.

A target that fails produces a row with an error field instead of a file, and the run carries on with the next target.

Pricing

This actor is pay per event:

EventPriceWhen
Actor start$0.005Once, when the run starts
Successful render$0.003Per URL or HTML input rendered successfully

So a run that screenshots 100 URLs costs about $0.305 — $0.005 to start plus 100 × $0.003.

Failed renders are not charged. If a page times out or errors, you get a dataset row with the error message and no charge for it.

Implementation note for maintainers: the event definitions live in two places that must be kept in sync — .actor/pay_per_event.json as a standalone file, and a payPerEvent.actorChargeEvents block inside .actor/actor.json. Apify has used both conventions; carrying both means the platform finds the pricing whichever key it reads. Change one, change the other.

Also available as a hosted REST API

If you'd rather call an endpoint than run an actor, the same renderer is available as a REST API at snaplab.dev:

curl -X POST https://snaplab.dev/api/render \
-H "Authorization: Bearer sk_..." -H "Content-Type: application/json" \
-d '{"url":"https://example.com","format":"png","fullPage":true}' -o shot.png

100 free renders a month, plus PDF, HTML→image, signed URLs for <img> tags, an n8n community node, and an MCP server at https://snaplab.dev/mcp so Claude and Cursor can see any page. Docs: snaplab.dev/docs.

FAQ

Can I render pages behind a login? Not in v1. There is no cookie, header or credential input yet, so every page is fetched as an anonymous visitor. Public pages, paywall-free articles and your own marketing pages all work fine.

Why is my full-page screenshot cut off? Very long pages hit chromium's own capture limits, and many sites only load images as you scroll. Set delay to 1000–3000 ms so lazy-loaded content has time to appear before the capture. If the page is genuinely enormous, capture it as a PDF instead.

Does PDF mode respect width and height? No. In PDF mode the page size comes from pdfFormat (A4, Letter, Legal, A3, A5) and landscape. The width/height inputs only shape the browser viewport used for screenshots.

What happens if one URL fails? You get a dataset row containing that URL and an error message, the run continues to the next target, and you are not charged the render event for it.

Can I get JPEG at a specific quality? Not in v1 — JPEG quality is fixed at 80, which is a good size/fidelity trade-off for page captures. Use png or webp if you need lossless or smaller lossless-ish output.

How do I get the file? Every dataset row carries a keyValueStoreUrl. That URL points at the record in the run's key-value store; fetch it to download the PNG, JPEG, WebP or PDF.

Does this actor call the snaplab API? No. It is self-contained: it launches its own Playwright chromium on the Apify platform, so an Apify run needs no snaplab account or key. The hosted API above is the same capability behind a REST endpoint, for when you want to call it from your own code.

Changelog

0.1

  • Initial release: URL and raw-HTML rendering, screenshot (PNG/JPEG/WebP) and PDF modes, full-page capture, ad and tracker blocking, cookie-banner removal, dark mode, custom viewport, render delay, pay-per-event pricing.