Menu

Clean screenshots

Remove cookie banners, ads, trackers and chat widgets, hide elements, inject CSS and JavaScript, click and wait.

Remove the clutter

Turn on the blockers you need:

curl -X POST "https://shotkit.net/api/take" \
  -H "X-Access-Key: YOUR_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com","block_cookie_banners":true,"block_ads":true,"block_trackers":true,"block_chats":true}' \
  --fail-with-body -o shot.jpg
Option What it does
block_cookie_banners Blocks consent-manager scripts (OneTrust, Cookiebot, Didomi, Usercentrics, …), hides their elements, and re-enables scrolling they lock.
block_banners_by_heuristics Also removes fixed or sticky overlays that look like banners, modals or newsletter popups. Aggressive, so check the result.
block_ads Blocks requests to ad networks.
block_trackers Blocks analytics and tracking scripts. Pages often load faster too.
block_chats Blocks and hides chat widgets (Intercom, Drift, Crisp, HubSpot, …).

Blocked requests never load, so nothing flashes on screen and nothing is left to hide.

Block anything else

block_requests takes wildcard patterns matched against request URLs, and block_resources blocks whole resource types:

curl -X POST "https://shotkit.net/api/take" \
  -H "X-Access-Key: YOUR_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com","block_requests":["*.doubleclick.net/*","*/analytics.js"],"block_resources":["media","font"]}' \
  --fail-with-body -o shot.jpg

Resource types: document, stylesheet, image, media, font, script, texttrack, xhr, fetch, eventsource, websocket, manifest, other. The page itself is never blocked.

Hide or restyle elements

hide_selectors hides every element matching any selector. styles injects any CSS:

curl -X POST "https://shotkit.net/api/take" \
  -H "X-Access-Key: YOUR_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com","hide_selectors":[".newsletter-popup","#promo-bar"],"styles":"header { position: static !important } body { font-size: 18px }"}' \
  --fail-with-body -o shot.jpg

Run JavaScript

scripts runs in the page after it loads, before the capture. Use it to open sections, fill in demo data or remove things CSS can't reach:

curl -X POST "https://shotkit.net/api/take" \
  -H "X-Access-Key: YOUR_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com","scripts":"document.querySelectorAll('\''details'\'').forEach(d => d.open = true)"}' \
  --fail-with-body -o shot.jpg

If the script throws, the request fails with script_triggers_error. If it navigates (submitting a form, following a link), set scripts_wait_until so the capture waits for the next page. On sites with a strict Content-Security-Policy, scripts that load other scripts may need bypass_csp=true.

Click and hover

click and hover act on the first visible element matching a selector, after scripts:

curl -X POST "https://shotkit.net/api/take" \
  -H "X-Access-Key: YOUR_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com","click":"button.load-more","delay":1}' \
  --fail-with-body -o shot.jpg

By default a missing element fails the request with selector_not_found. Set error_on_click_selector_not_found=false (or the hover equivalent) for elements that are only sometimes there, like a promo popup.

Wait for the right moment

By default the capture happens after the load event, once the network has been briefly idle, the page has stopped changing, and fonts and visible images have loaded (each capped at a few seconds). For pages that render even later:

Option Waits for
wait_until load, domcontentloaded, networkidle0 (no requests for 500 ms) or networkidle2 (at most 2).
wait_for_selector An element to appear, such as a chart rendered by JavaScript.
delay A fixed number of seconds, for animations.
curl -X POST "https://shotkit.net/api/take" \
  -H "X-Access-Key: YOUR_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com","wait_until":["networkidle0"],"wait_for_selector":".chart canvas"}' \
  --fail-with-body -o shot.jpg

Prefer wait_for_selector over delay: it's as fast as the page allows and fails clearly with selector_not_found if the content never shows up.

Freeze animations

reduce_motion=true finishes CSS animations and transitions and pauses videos, so hero sections aren't caught half-faded. dark_mode=true renders sites that support it in dark mode.

curl -X POST "https://shotkit.net/api/take" \
  -H "X-Access-Key: YOUR_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com","reduce_motion":true,"dark_mode":true}' \
  --fail-with-body -o shot.jpg

Fail instead of capturing a broken page

When screenshots feed something automated, a picture of an error page is worse than an error. These options fail the request instead:

curl -X POST "https://shotkit.net/api/take" \
  -H "X-Access-Key: YOUR_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/product/42","fail_if_content_missing":["Add to cart"],"fail_if_content_contains":["Access denied"],"fail_if_request_failed":["*api.example.com*"]}' \
  --fail-with-body -o shot.jpg

A 4xx or 5xx from the page itself already fails with host_returned_error unless ignore_host_errors=true. Failed requests don't count toward your monthly screenshots.