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.jpgResource 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.jpgRun 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.jpgIf 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.jpgBy 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.jpgPrefer 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.jpgFail 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.jpgA 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.