ScreenshotNeo

BlogHow-to

Microlink API Example for Screenshots in Python

Capture a webpage with Microlink in Python, retrieve its screenshot, and handle common options and errors. See a one-call ScreenshotNeo alternative.

By the ScreenshotNeo team4 October 20268 min read

To take a screenshot with Microlink in Python, send a GET request to https://api.microlink.io/ with the target page in url and screenshot=true. Microlink returns JSON; the hosted screenshot URL and its image metadata are under data.screenshot. This example checks both the HTTP response and Microlink’s API-level status before saving the image.

import requests

API_URL = "https://api.microlink.io/"
PAGE_URL = "https://www.netflix.com/title/80057281"

try:
    response = requests.get(
        API_URL,
        params={"url": PAGE_URL, "screenshot": "true"},
        timeout=90,
    )
    response.raise_for_status()
    payload = response.json()
except requests.RequestException as exc:
    raise SystemExit(f"Microlink request failed: {exc}")
except ValueError as exc:
    raise SystemExit(f"Microlink returned invalid JSON: {exc}")

if payload.get("status") != "success":
    raise SystemExit(f"Microlink API error: {payload}")

screenshot = payload.get("data", {}).get("screenshot")
if not screenshot or not screenshot.get("url"):
    raise SystemExit(f"Response did not include a screenshot URL: {payload}")

print("Screenshot URL:", screenshot["url"])
print("Image details:", {
    "width": screenshot.get("width"),
    "height": screenshot.get("height"),
    "type": screenshot.get("type"),
    "size": screenshot.get("size"),
})

image_response = requests.get(screenshot["url"], timeout=90)
image_response.raise_for_status()
with open("screenshot.png", "wb") as image_file:
    image_file.write(image_response.content)

print("Saved screenshot.png")

The target URL above follows Microlink’s documented example. Change it to a publicly reachable page you are authorized to capture. The extension in the output filename does not convert the image; use the returned content type or configure the screenshot output format before choosing an extension.

1. Install the Python dependency

python -m pip install requests

Save the code as capture.py and run python capture.py. Microlink’s basic screenshot request can be tried without an API key. Its published free allowance and plan features can change, so check the current screenshot guide for the terms that apply to your account.

2. Understand the request and response

The request has two essential parameters:

  • url: an absolute target address beginning with http:// or https://. It must be publicly reachable by Microlink.
  • screenshot=true: asks Microlink to capture the target page.

The response is JSON with a top-level status and a data.screenshot object. Depending on the response, that object can include the hosted asset url, dimensions, type, byte size, and a human-readable size. Read data.screenshot.url after confirming success; download that URL if you need a local image file.

For diagnosis, inspect the full JSON response rather than assuming a successful HTTP status means a successful capture. Microlink documents API statuses including success, fail, and error.

3. Useful screenshot options

Capture a specific element

Add an element selector to capture one region instead of the usual page screenshot:

params = {
    "url": "https://example.com",
    "screenshot": "true",
    "element": "#section-hero",
}
response = requests.get("https://api.microlink.io/", params=params, timeout=90)
response.raise_for_status()
print(response.json())

Replace #section-hero with a CSS selector that exists on the target page. If the page renders that element only after interaction or delayed loading, the capture may not contain the expected content.

Skip metadata extraction

If you only need the screenshot, add meta=false. Microlink says metadata extraction is usually the biggest speedup when the image is the only required output:

params = {
    "url": "https://example.com",
    "screenshot": "true",
    "meta": "false",
}

Return the image instead of JSON

By default, Microlink returns JSON containing screenshot metadata and an asset URL. If the consumer needs the image response directly, the documented embed option is embed=screenshot.url. This changes the response shape, so do not call response.json() for that request; handle the response body as image bytes instead. Consult the embed parameter reference for current behavior.

Full-page, viewport, and image settings

Microlink documents full-page capture and options for screenshot type and viewport width, height, and device scale factor. These affect image dimensions and capture scope. Check the current screenshot parameter reference for exact parameter names and accepted values before adding them. Use viewport capture when you need a predictable screen-sized image; full-page capture when the whole document is needed; and an element selector when only one component matters.

4. cURL example

curl -G "https://api.microlink.io/" \
  --data-urlencode "url=https://www.netflix.com/title/80057281" \
  --data-urlencode "screenshot=true"

The default response is JSON. To save the image, extract data.screenshot.url from the JSON and download that asset URL. If you configure an embedded image response, write the response body directly to a file instead.

5. Node.js example

const params = new URLSearchParams({
  url: 'https://www.netflix.com/title/80057281',
  screenshot: 'true',
});

const response = await fetch(`https://api.microlink.io/?${params}`);
if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}

const payload = await response.json();
if (payload.status !== 'success') {
  throw new Error(`Microlink API error: ${JSON.stringify(payload)}`);
}

const screenshotUrl = payload.data?.screenshot?.url;
if (!screenshotUrl) {
  throw new Error('Response did not include data.screenshot.url');
}
console.log('Screenshot URL:', screenshotUrl);
console.log('Image details:', payload.data.screenshot);

This example uses the built-in fetch available in modern Node.js versions. It prints the asset URL; download it with a second fetch if your application needs a local file.

6. Private pages, keys, and URL safety

The target must be reachable by Microlink. For pages behind login, Microlink’s documentation says forwarding cookies or tokens requires Pro. Its instructions use x-api-header-* request headers with pro.microlink.io. Keep credentials on your server, never in browser JavaScript or query strings, and only send session data for pages you are authorized to access. See Microlink’s use-case documentation for the current private-page guidance.

If the target address itself contains a query string, use a client’s parameter encoder, as in the Python example, rather than concatenating the target URL into the API URL. This ensures the target’s parameters remain part of the url value.

Microlink documents x-api-key authentication for pro.microlink.io. Its API overview also documents rate limit headers named x-rate-limit-limit, x-rate-limit-remaining, and x-rate-limit-reset. Check these when handling sustained workloads; an exceeded quota is documented as HTTP 429 with code ERATE. Plan terms and limits can change.

7. Troubleshooting

Symptom Likely cause What to do
HTTP 400 or an API failure status Missing or malformed target URL, unsupported option, or invalid parameter value. Send a complete https:// URL, encode parameters with requests, and verify option names against the current parameter reference.
HTTP 429 or ERATE The account’s request quota or rate limit was reached. Read the rate limit headers, wait until the documented reset, and review the account’s current plan and usage.
HTTP request timeout The target page or capture took longer than the client timeout. Set a reasonable client timeout, retry transient failures with a bounded backoff, and check whether the target is reachable without authentication. Avoid unbounded retries.
HTTP success but no screenshot URL The API-level status may be fail or error, or the response may not have the expected data. Check payload.status and print the complete response for diagnosis before accessing nested fields.
Image download fails The hosted asset request failed or the URL is no longer usable. Check the asset request’s status and download it promptly. If the API response is configured to embed the image, save those response bytes instead.
Wrong or incomplete area in the capture The selected element is absent, content loads later, or viewport/full-page settings do not match the intended capture. Confirm the selector against the rendered page and review the documented screenshot and viewport options.
Target query parameters are lost or misread The target URL was concatenated without encoding. Pass it as the url value through requests.get(..., params=...).
Private page renders logged out Microlink cannot access the page’s session. Use the documented Pro private-page header approach from a backend, or capture a public page. Do not expose session credentials in URLs or client-side code.

8. Performance, reliability, and cost

For image-only workflows, meta=false avoids metadata extraction and is the clearest documented speed optimization. Choose the smallest capture scope that serves the task: a viewport, one element, or the full page. Large full-page images take more data to transfer and store than a small selected region.

Set explicit network timeouts in your client. For batch or production jobs, distinguish transport failures from API-level failures, preserve response details for debugging, and use bounded retries for transient errors. Avoid retrying quota errors immediately. Microlink documents a 99.9% uptime SLA on paid plans; this is the vendor’s stated SLA, not a guarantee that every target page will capture successfully. The vendor documentation describes 25 free requests per day; confirm current limits and plan features before relying on that allowance. Configurable TTL, stale-while-revalidate caching, custom filenames, custom headers, and proxy are listed as plan features in its guide.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. One GET request returns an image or PDF; the API supports PNG, JPEG, and WebP screenshots. Its clean-shot steps can accept cookie banners like a visitor and remove more than 60 known consent platforms, newsletter popups, and chat widgets, with each step switchable. Bot checks, blank pages, failed loads, timeouts, and cache hits cost nothing, and response headers report the page verdict and billing status. AI agents can use its MCP tools, including take_screenshot, get_page_info, and capture_pdf.

Here is the Python call for a WebP screenshot. See the ScreenshotNeo API documentation for request options.

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

Equivalent cURL and Node.js calls:

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -o shot.webp
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
await Bun.write('shot.webp', res);

ScreenshotNeo includes full-page capture with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets and custom viewports, retina scale, PDF settings, custom CSS and JavaScript, click and hide selectors, wait conditions, request and resource blocking, custom headers and cookies, user agent and Authorization, timezone and geolocation, transparent backgrounds, resizing, cache TTL, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, usage API, and OpenAPI spec. Parameter names used by other screenshot APIs also work to make migration easier.

The free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000; higher plans are $15 for 15,000, $39 for 60,000, $99 for 250,000, and $249 for 1,000,000. Yearly billing gives two months free, and every feature is on every plan. Create a free ScreenshotNeo account to get 1,000 screenshots a month with no card.

FAQ

Yes. Pass the full target as the url parameter through a query-encoding client such as Python Requests’ params argument.

Does the Python example return image bytes directly?

The default response is JSON with screenshot metadata and a hosted image URL. Download that URL for a local file, or use Microlink’s documented embed option when a direct image response suits your workflow.

Can I use this for pages that require login?

Microlink documents forwarding cookies or tokens for private pages as a Pro capability. Send credentials from a trusted backend using its documented header method, and avoid putting secrets in URLs.