A screenshot API that survives production

URL in, image out. One GET request, binary response, no JSON envelope to unwrap — so the URL works directly inside an <img src>.

GET /take?url=https%3A%2F%2Fexample.com
Try it — no signup, no key.

Most screenshot failures are not crashes

They are a 200 with the wrong picture: a consent wall, a half-loaded page, a blank frame your pipeline records as a success. We built a 202-page benchmark of the real web to find them, and each of these is a fix it forced.

Banners injected after load

A one-shot sweep loses that race. We install an observer before any page script runs, so a banner that appears two seconds late is still removed.

Ad slots that leave a hole

Blocking the request does not reclaim the space. Most tools leave a grey gap that pushes content below the fold. We collapse the empty slot.

Pages that never go idle

Waiting for an event modern sites never emit turns a 3-second capture into a timeout. We wait for interactive, then spend one bounded settle budget.

Pages that wedge themselves

Some pages block their own main thread and stop answering. Every wait has a ceiling, so one stuck page cannot hold a slot or hang your request.

Blank captures

Detected with two independent signals and reported in a header. A bot wall is never silently returned as a success — or billed as one.

Keys in public HTML

The headline use case is <img src>, where a raw key is a billing incident waiting to happen. HMAC signed URLs are a v1 feature.

Measured against the incumbents

18 news front pages — consent walls, lazy images, heavy embeds — captured through all three APIs on the same day at the same viewport.

18 news pagesScreenshotlineScreenshotOneApiFlash
Captured18/1817/1818/18
timesofindia.com414 KB261 KB358 KB
Pages within 10% of the best13 of 17

Bytes are a proxy for how much of the page actually rendered. We publish the method rather than a marketing claim — and the one page we lose on is blocked at the network edge, not mis-rendered.

Also returns the page as Markdown

Same render — JavaScript executed, banners dismissed, lazy images loaded — read as text instead of photographed. Built for feeding live pages to models.

curl "https://api.screenshotline.com/extract?url=https%3A%2F%2Fexample.com&access_key=KEY"
A plain fetch of app.netlify.com returns 121 characters of visible text, and they read "The Netlify dashboard needs JavaScript :(". Rendered first, the same URL returns the actual page. There is an MCP server too, so agents can call it directly.

Pricing

Free
$0
100 renders — no card
Starter
$17/mo
2,000 renders
Growth
$79/mo
10,000 renders
Scale
$259/mo
50,000 renders
Failed renders and cache hits are never billed. Most APIs promise this; blank detection is what lets us mean it literally.
Start free — no card Full pricing Read the docs

Parameters

urlRequired. http or https. Private and reserved addresses are refused.
formatpng (default), jpeg, webp, pdf
full_pageCapture the whole document. Scrolls first so lazy images load.
selectorCapture one element instead of the viewport.
viewport_width
viewport_height
Defaults 1280×800.
device_scale_factor2 for retina output.
block_ads
block_cookie_banners
Blocks the networks and sweeps leftover overlays.
delayExtra wait in ms before capture, max 10000.
wait_untildomcontentloaded (default), load, networkidle0, networkidle2. The default is deliberate — see the docs.
cache
cache_ttl
Serve from the store when warm. TTL in seconds.
access_keyOr the X-Access-Key header.
signatureHMAC of the sorted query. Required for browser-visible URLs.

Full docs, with copy-paste quickstarts for curl, Node, Python, PHP and Go.