ScreenshotNeo

BlogGuides

Screenshot API Options and Settings in Python

A complete Python guide to screenshot API options: formats, cookies, CSS, geolocation, browser emulation, errors, and production patterns.

By the ScreenshotNeo team29 September 20269 min read

Screenshot API Options and Settings in Python

Use a screenshot API when you need a rendered browser view without installing or operating a browser in your application. In Python, send a GET request to https://shot.screenshotapi.net/v3/screenshot, authenticate with token, provide url, choose an output format, and write the response bytes to a file. The same request can preserve cookies, inject CSS, emulate a client, set geolocation, add headers, or route traffic through a proxy.

This guide explains the documented ScreenshotAPI.net options, provides runnable Python, cURL, and Node.js examples, and covers the edge cases that usually cause blank, unauthorized, or incorrectly sized captures. At the end, you will also see a browser-free option from ScreenshotNeo.

1. The basic Python request

The shortest useful implementation uses requests. The API returns the rendered file when output=image is selected.

A Python client sends options to the render endpoint and saves the returned bytes.
A Python client sends options to the render endpoint and saves the returned bytes.
import requests

TOKEN = "YOUR_API_KEY"
params = {
    "token": TOKEN,
    "url": "https://example.com",
    "output": "image",
    "file_type": "png",
}

response = requests.get(
    "https://shot.screenshotapi.net/v3/screenshot",
    params=params,
    timeout=60,
)
response.raise_for_status()

with open("screenshot.png", "wb") as image_file:
    image_file.write(response.content)

print("Saved screenshot.png")

requests URL-encodes the query parameters for you. Keeping the URL in params, rather than concatenating it into the endpoint string, avoids errors with query strings, ampersands, spaces, and non-ASCII characters.

Using Python’s standard library

If you do not want a third-party dependency, urllib follows the same request model.

import urllib.parse
import urllib.request

TOKEN = "YOUR_API_KEY"
target = urllib.parse.quote_plus("https://example.com")
query = (
    "https://shot.screenshotapi.net/v3/screenshot"
    f"?token={TOKEN}&url={target}&output=image&file_type=png"
)
urllib.request.urlretrieve(query, "screenshot.png")

Keep the token out of source control. Read it from an environment variable or your deployment secret store in production.

2. cURL and Node.js equivalents

cURL

curl -G "https://shot.screenshotapi.net/v3/screenshot" \
  --data-urlencode "token=YOUR_API_KEY" \
  --data-urlencode "url=https://example.com" \
  --data-urlencode "output=image" \
  --data-urlencode "file_type=png" \
  -o screenshot.png

Node.js

const params = new URLSearchParams({
  token: 'YOUR_API_KEY',
  url: 'https://example.com',
  output: 'image',
  file_type: 'png'
});

const response = await fetch(
  `https://shot.screenshotapi.net/v3/screenshot?${params}`
);

if (!response.ok) {
  throw new Error(`Screenshot request failed: ${response.status}`);
}

const image = Buffer.from(await response.arrayBuffer());
await require('node:fs').promises.writeFile('screenshot.png', image);

3. Response type and file format

Setting What it does When to use it
output=image Returns raw rendered media bytes. Save or stream a PNG, JPG, WebP, or supported document format.
output=JSON Returns structured render information. Inspect render results or metadata before deciding what to store.
file_type Selects the output media/document format. Choose PNG for lossless UI detail, JPG for smaller photographic images, WebP where your consumer supports it, or PDF where supported.

The documented examples use file_type=png. Check the service documentation for the exact formats enabled for your account and endpoint version before hard-coding validation rules. A binary response must be written with wb in Python; opening it as text corrupts the file.

Saving a different format

params = {
    "token": TOKEN,
    "url": "https://example.com",
    "output": "image",
    "file_type": "webp",
}
response = requests.get(
    "https://shot.screenshotapi.net/v3/screenshot",
    params=params,
    timeout=60,
)
response.raise_for_status()
with open("screenshot.webp", "wb") as image_file:
    image_file.write(response.content)

4. Page source and visual controls

Capture supplied HTML with custom_html

custom_html renders supplied markup instead of loading the URL. URL-encode the HTML, especially when it contains CSS, ampersands, quotes, or inline SVG. This is useful for invoices, generated reports, and deterministic templates.

html = """
<!doctype html>
<html>
  <body>
    <h1>Invoice 1042</h1>
    <p>Total: $120.00</p>
  </body>
</html>
"""
params = {
    "token": TOKEN,
    "url": "https://example.com",  # required by some clients; custom_html takes precedence
    "custom_html": html,
    "output": "image",
    "file_type": "png",
}
response = requests.get("https://shot.screenshotapi.net/v3/screenshot", params=params, timeout=60)
response.raise_for_status()
open("invoice.png", "wb").write(response.content)

Hide elements with CSS

The css option injects CSS before capture. Hide cookie notices, navigation, ads, or test-only elements with a selector. For example, .module-content{display:none} removes matching content from the rendered image. Escape CSS correctly when passing it in a shell command or as a Python parameter.

params = {
    "token": TOKEN,
    "url": "https://example.com/article",
    "css": ".cookie-banner, .newsletter-modal { display: none !important; }",
    "output": "image",
    "file_type": "png",
}

Prefer a narrow selector. Hiding a broad container such as body can produce a blank result and make the failure look like a network problem.

5. Cookies, authentication, and request state

Pass cookies when the page changes based on a session, consent choice, feature flag, or login. The documented syntax supports semicolon-separated cookie pairs.

CSS, cookies, and consent handling determine what appears in the final capture.
CSS, cookies, and consent handling determine what appears in the final capture.
params = {
    "token": TOKEN,
    "url": "https://example.com/account",
    "cookies": "session_id=abc123; theme=dark; consent=yes",
    "output": "image",
    "file_type": "png",
}
response = requests.get("https://shot.screenshotapi.net/v3/screenshot", params=params, timeout=60)
response.raise_for_status()
open("account.png", "wb").write(response.content)

Only send cookies that are necessary for the capture. Treat session cookies as credentials: do not log the complete query string, commit it to code, or expose it in client-side JavaScript. If a login flow requires several browser interactions rather than a reusable cookie, the API request may not reproduce that state; create a valid session first or use a capture service that supports scripted actions.

6. Browser and network emulation

These options let you reproduce the context in which a page is rendered:

Option Purpose Example
user_agent Represent a browser, device, crawler, or application. Desktop or mobile user-agent string
accept_languages Set the browser language preference. en-US,en;q=0.9
headers Send custom HTTP headers before rendering. Preview or authorization headers
proxy Route the request through a network address, optionally with authentication. Regional or internal-network testing
latitude, longitude Set browser geolocation context. Numeric coordinates for a localised page
params = {
    "token": TOKEN,
    "url": "https://example.com/store",
    "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 Mobile/15E148 Safari/604.1",
    "accept_languages": "fr-FR,fr;q=0.9",
    "headers": "X-Preview: true; X-Request-Source: screenshot",
    "latitude": "48.8566",
    "longitude": "2.3522",
    "output": "image",
    "file_type": "png",
}

Use a fixed set of emulation values in visual regression jobs. Changing the user agent, language, cookies, or coordinates can legitimately change text, layout, prices, and available content.

7. A practical option checklist

  1. Start with url, output=image, and a known file_type.
  2. Add custom_html only when the page is generated markup rather than a URL.
  3. Add css for deterministic visual cleanup.
  4. Add cookies for consent, sessions, or feature flags.
  5. Add user_agent and accept_languages when reproducing a client experience.
  6. Add headers for preview or request metadata.
  7. Add latitude and longitude for location-sensitive pages.
  8. Add proxy when the page must be fetched from a specific network origin.

8. Troubleshooting common failures

Symptom Likely cause Fix
401 or authentication error Missing, invalid, or rotated token. Read the current token from your secret store. Rolling a key revokes the previous key, so update every worker.
400 or malformed request Unencoded URL, CSS, HTML, or headers. Pass values through requests parameters or --data-urlencode; do not build a raw query string manually.
Downloaded file will not open Binary bytes were saved as text, or an error body was saved as an image. Use wb, call raise_for_status(), and inspect the response content type before storing.
Blank page The URL failed, content is hidden, JavaScript did not finish, or CSS selected a parent container. Open the URL directly, remove the CSS rule, verify cookies and headers, and try a simpler page.
Login page instead of account page Cookies are absent, expired, scoped to another domain, or formatted incorrectly. Send the required cookie pairs with the documented semicolon syntax and confirm they belong to the target domain.
Wrong language or location Missing or conflicting language and geolocation settings. Set accept_languages and numeric coordinates explicitly; keep them fixed between comparisons.
Layout differs from a user’s browser User agent, viewport defaults, fonts, or responsive breakpoints differ. Set an appropriate user_agent and compare the same client context consistently.
Requests time out The page or a third-party resource is slow. Use a bounded timeout, retry transient failures with backoff, and capture a simpler URL to isolate the slow dependency.

9. Reliability, performance, and cost considerations

Screenshot work is render work, so response time depends on the page, its scripts, images, and external resources. Keep your application responsive by setting a client timeout, limiting concurrent requests to the service limits on your plan, and retrying only transient network or server failures. Do not blindly retry authentication or malformed-request errors.

For repeatable output, use stable URLs, explicit cookies and emulation values, and a consistent format. Store a content hash with each capture if you need deduplication. PNG preserves sharp text but can be larger; JPG and WebP can reduce storage when their quality characteristics fit your use case. If you request JSON output, retain the structured result for diagnostics instead of discarding it.

Estimate cost from the number of successful renders, output size, storage, and retries. Cache identical requests in your own application when the page does not change frequently. Before production rollout, confirm the current provider limits, supported formats, and account pricing in the provider documentation; the research material for this guide does not specify quota or price figures.

10. Or skip the browser setup

ScreenshotNeo provides a single GET request for a PNG, JPEG, WebP, or PDF. Its capture flow accepts cookie and consent banners like a visitor, then removes more than 60 known consent platforms, newsletter popups, and chat widgets. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response reports the page verdict and billing status in X-Page-Verdict and X-Billed headers. Every feature is available on every plan, including an MCP server with take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

See the ScreenshotNeo API documentation for the complete option list. The minimal call is:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
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)
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(`ScreenshotNeo request failed: ${res.status}`);

ScreenshotNeo also supports full-page captures with lazy images loaded, CSS element capture, dark mode, device presets and custom viewports, retina scale, PDF paper and page settings, custom CSS and JavaScript, clicks, selector or network-idle waits, request blocking, custom headers and cookies, user agents, timezone and geolocation, transparent backgrounds, resizing, TTL caching, signed links, asynchronous jobs with signed webhooks, bulk capture for up to 100 URLs per call, a usage API, and an OpenAPI specification. Parameter names used by other screenshot APIs also work, which can simplify migration.

The Free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; yearly billing gives two months free. Create a free ScreenshotNeo account.

11. FAQ

Can I return metadata instead of an image?

Yes. Set output=JSON when you need structured render information rather than raw media bytes.

How do I hide one element without changing the source page?

Pass a CSS rule through css, targeting the element’s selector and using display:none when appropriate.

Which option handles an authenticated page?

Use cookies for an existing session and headers for request metadata. Verify that the values are current and scoped to the target site.

Can geolocation change the screenshot?

Yes. latitude and longitude set the browser geolocation context, which can affect local content and availability.

Should I use a URL or custom HTML?

Use url for a live website. Use custom_html for markup your application generates and wants rendered directly.