Screenshot blocked websites without managing a proxy list
To screenshot blocked websites you need more than a headless browser: a challenge page, a 403 or an endless spinner is what bot protection serves to datacenter traffic. Price monitoring, competitive research, archiving and link previews all hit that wall sooner or later. Instead of buying and rotating proxies yourself, send the capture with your API key and the Screenshot API resolves the proxy for you, with no extra option.
A screenshot of a blocked website shows the bot wall, not the page
Datacenter IPs and headless fingerprints are exactly what antibot services look for. Cloudflare, DataDome, Akamai and similar shields answer with a challenge or a block, and your screenshot shows the wall instead of the page. With a self-hosted browser the navigation still succeeds, so nothing in your pipeline flags the image as useless.
Running your own proxies is a second product to maintain. You buy a pool, rotate exits, retire the burned ones, match the proxy type to each antibot vendor and keep the credentials out of your URLs and logs. The list that works this month stops working the next, and every failure looks like a blank capture.
With an API key the proxy is on by default, the free key included. When a capture hits a 403 wall, Microlink detects the antibot provider and escalates through proxy tiers, ending on residential exits: the slowest route, and the one that usually gets through. The tier that worked is cached per domain, so the next capture of that site goes straight to it. On the keyless endpoint the same target fails with EPROXYNEEDED instead.
How to screenshot a Cloudflare-protected site through the proxy
Send protected targets with your API key and the proxy resolves itself. If you start on the keyless endpoint, EPROXYNEEDED marks the URLs to move to the key. The proxy guide lists every signal that a target needs one.
import createClient from 'microlink.io'
const microlink = createClient({
apiKey: process.env.MICROLINK_API_KEY
})
const { url } = await microlink.screenshot('https://hard-target.com')The client carries your API key, so a blocked capture escalates through the proxy tiers on its own and returns the same asset object as any screenshot: url, width, height, type and size. There is no parameter to add, no list to maintain and no proxy credential in the request.
import createClient from 'microlink.io'
const microlink = createClient({
apiKey: process.env.MICROLINK_API_KEY
})
const freeTier = createClient()
const capture = async target => {
try {
return await freeTier.screenshot(target)
} catch (error) {
if (error.code !== 'EPROXYNEEDED') throw error
return microlink.screenshot(target, { retry: 3 })
}
}EPROXYNEEDED means the target uses antibot protection and needs an API key. Only those URLs move to the keyed client, where the proxy resolves automatically, with retry raised to 3 for intermittent challenges.
curl 'https://pro.microlink.io/?url=https%3A%2F%2Fhard-target.com&screenshot=true&meta=false' \
-H 'x-api-key: $MICROLINK_API_KEY'The proxy comes with every API key, so the URL targets pro.microlink.io with the x-api-key header and no proxy parameter. An x-fetch-mode response header ending in -proxy, such as prerender-proxy, confirms the route.
- proxy Automatic with any API key, no value needed. Pass an object with location or url only to pin a country or bring your own server.
- proxy.location Two-letter ISO country code that pins the exit country of the proxy. Default us. Any API key.
- retry Server-side retries with exponential backoff for intermittent challenges. Default 2.
- headers Forwards a language or a custom header when the target expects one. Any API key.
- ttl Caches the unblocked capture from 1 minute to 31 days so repeat calls skip the proxy path entirely. Any API key.
Confirm the proxy was used with the x-fetch-mode response header: any value ending in -proxy means the request went through it. If a capture still fails, the screenshot troubleshooting guide walks through timing, blocking and plan errors in order.
Why a built-in proxy beats maintaining your own proxy list
A proxy is only useful if it is the right proxy, at the right time, without leaking credentials into your screenshot URLs. Building it into the API removes three chores.
The resolution works on every product, so the same API key unblocks a Markdown conversion of a bot-protected page or a metadata request for the same site.
The signal surfaces on the keyless endpoint. Automatic proxy resolution comes with every API key, the free one included, so a request sent with your key from the start never needs the keyless fallback.
When not to: the proxy does not log you into anything. For pages behind authentication, forward the session as a request header instead. If the site is also bot-protected, your API key handles the proxy on top.
FAQ
Is the proxy for screenshots of blocked websites included in the price?
How do I know a screenshot was taken through the proxy?
How do I screenshot a Cloudflare-protected site?
Can I choose the country of the screenshot proxy?
Why is the first screenshot of a protected site slower?
Solve the next problem with the same API
Screenshot a site from another country
Screenshots behind a login
Screenshots of JavaScript-rendered pages
Screenshots under traffic spikes
Markdown from bot-protected pages
Link previews for bot-protected sites
Ready to screenshot hard targets?
No option, no proxy list. Get your free API key and capture the pages that block everyone else.