Skip to content
Screenshot API · Use case

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, add one option and the Screenshot API resolves the proxy for you.

The problem

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.

On Pro plans Microlink includes automatic proxy resolution: it detects the antibot provider blocking the request and routes it through a rotating proxy pool tested against the 500 most popular websites. When a direct request is refused, the API says so with the EPROXYNEEDED error code, and proxy: true sends the same capture through the pool.

How it works

How to screenshot a Cloudflare-protected site through the proxy

Start without a proxy, catch EPROXYNEEDED, retry with proxy: true. Or pass it upfront for targets you already know are protected. The proxy guide lists every signal that a target needs one.

1 · Capture through the managed proxy
import createClient from 'microlink.io'

const microlink = createClient({
  apiKey: process.env.MICROLINK_API_KEY
})

const { url } = await microlink.screenshot('https://hard-target.com', {
  proxy: true
})

proxy: true routes the capture through the managed proxy pool and returns the same asset object as any screenshot: url, width, height, type and size. There is no list to maintain and no proxy credential in the request.

2 · Only when the target needs it
import createClient from 'microlink.io'

const microlink = createClient({
  apiKey: process.env.MICROLINK_API_KEY
})

const capture = async target => {
  try {
    return await microlink.screenshot(target)
  } catch (error) {
    if (error.code !== 'EPROXYNEEDED') throw error
    return microlink.screenshot(target, { proxy: true, retry: 3 })
  }
}

EPROXYNEEDED means the target refused a direct request. Retrying only those targets through the proxy, with retry raised to 3 for intermittent challenges, keeps every other capture on the direct route.

3 · The same request as a URL
curl 'https://pro.microlink.io/?url=https%3A%2F%2Fhard-target.com&screenshot=true&meta=false&proxy=true' \
  -H 'x-api-key: $MICROLINK_API_KEY'

proxy requires a Pro key, so the URL targets pro.microlink.io with the x-api-key header. An x-fetch-mode response header prefixed with proxy-, such as prerender-proxy, confirms the route.

Parameters used
  • proxy true for automatic resolution, an object with location or url, or a bare proxy URL string. Pro plans.
  • proxy.location Two-letter ISO country code that pins the exit country of the proxy. Default us. Pro plans.
  • 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. Pro plans.
  • ttl Caches the unblocked capture from 1 minute to 31 days so repeat calls skip the proxy path. Pro plans.

Confirm the proxy was used with the x-fetch-mode response header: any value prefixed with 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 it works

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.

01 · Resolved for you
The API decides when and how to route.
Microlink identifies the antibot provider blocking the request and routes it through a dedicated resolution path. You never maintain a pool, rotate IPs or debug which exit is burned, and the pool is tested against the 500 most popular websites.

The option works on every product, so the same flag unblocks a Markdown conversion of a bot-protected page or a metadata request for the same site.

02 · An explicit signal
EPROXYNEEDED tells you exactly when a proxy is required.
Instead of guessing from a blank image, the API rejects the direct request with a code you can catch. Retry with proxy: true only for the targets that need it, and every other capture stays on the direct route.

The signal surfaces on every plan, free tier included. Routing through the pool is a Pro capability, and sending proxy without a paid plan returns the EPROXY error.

03 · Bring your own if you must
proxy.url routes through your own provider.
If a contract or a region requires a specific proxy, pass its URL as proxy.url and Microlink still handles the browser, the retries and the errors around it. Every sub-request of the page, from redirects to assets, goes through that server.

When not to: the proxy does not log you into anything. For pages behind authentication, forward the session as a request header instead, and add the proxy only if the site is also bot-protected.

FAQ

Is the proxy for screenshots of blocked websites included in the price?

Yes. Automatic proxy resolution is included in every Pro plan, with no separate proxy bill. The free tier surfaces the EPROXYNEEDED signal but cannot route through the proxy.

How do I know a screenshot was taken through the proxy?

Check the x-fetch-mode response header. Values prefixed with proxy-, such as prerender-proxy, mean the request was routed through the proxy, and x-pricing-plan: pro confirms it ran on a paid plan.

How do I screenshot a Cloudflare-protected site?

Send the request with proxy: true on a Pro key. Sites protected by Cloudflare, DataDome, Akamai and similar antibot services refuse datacenter traffic, so rather than keeping a list of them, catch EPROXYNEEDED and retry those targets through the proxy.

Can I choose the country of the screenshot proxy?

Yes. Pass proxy.location with a two-letter ISO country code to pin the exit country; the default is us. See screenshot a website from another country for the full recipe.

Does the screenshot proxy solve CAPTCHAs?

The proxy is built to avoid the checks that trigger CAPTCHAs for datacenter traffic, not to solve a CAPTCHA once it is shown. When a page still presents a challenge, Microlink’s antibot detection reports which provider blocked it. See proxy resolution for what the unblocker covers.
Related use cases

Solve the next problem with the same API

Screenshot a site from another country

Pin the request to a country with a two-letter code and capture the prices and copy a local visitor sees.

Screenshots behind a login

Forward a session cookie or a bearer token as a request header and capture pages only your users can see.

Screenshots of JavaScript-rendered pages

Wait for a selector, a lifecycle event or a delay so single-page apps and lazy sections finish rendering before capture.

Screenshots under traffic spikes

Absorb bursts of screenshot traffic without a browser pool: no throttling, parallel requests and a cache whose hits are free.

Markdown from bot-protected pages

Convert pages behind Cloudflare, DataDome or Akamai: one option routes the request through the built-in proxy.

Link previews for bot-protected sites

Unfurl links to sites behind Cloudflare or DataDome by routing the metadata request through the built-in proxy.

Ready to screenshot hard targets?

One option, no proxy list. Get a Pro key and capture the pages that block everyone else.