Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallSome links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
To take a website screenshot in Python, send a GET request to https://shot.screenshotapi.net/v3/screenshot with your API token, target url, output=image, and a file_type. Save the response body as a binary file. The same endpoint can return JSON render information, load custom HTML, inject CSS, apply cookies, emulate a user agent and language, set browser geolocation, add headers, or route traffic through a proxy.
This guide starts with runnable Python, then explains each setting, authenticated and localized captures, failure recovery, and an API alternative when you do not want to manage a browser-rendering setup.
Minimal Python screenshot request
Install the HTTP client first:
python -m pip install requests
Use a parameter dictionary rather than manually concatenating the query string. The client URL-encodes the page URL and other values safely.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteimport 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(f"Saved {len(response.content)} bytes to screenshot.png")
token authenticates the request and url identifies the page to render. output=image returns the rendered media bytes, so write response.content in binary mode. A timeout prevents a stalled render from hanging your worker indefinitely.
#1 Best Overall
Python without third-party packages
The standard library works when you cannot install requests:
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")
Do not omit URL encoding when constructing a URL manually. Query characters in the target page, such as & or ?, otherwise become part of the screenshot API request itself.
Response type and file format
Rendered bytes with output=image
Choose output=image when your program needs a PNG, JPG, WebP, or supported PDF response. The response body is the file; there is no JSON wrapper to decode. Select the format with file_type and use a matching extension in your output filename.
Free tools Windows power users keep installed
One-click scans. No signup required.
| Goal | Settings | What Python receives |
|---|---|---|
| Lossless image for tests or archival | output=image, file_type=png |
PNG bytes |
| Smaller photographic image | output=image, a supported JPG or WebP file_type |
Encoded image bytes |
| Printable document | output=image, file_type=pdf where supported |
PDF bytes |
| Render diagnostics or metadata | output=JSON |
Structured response data rather than an image file |
Use output=JSON while debugging a URL or collecting render information. Switch to image in production when the consumer expects a media file. The service documentation should be checked for the currently supported file_type values before relying on a less common format.
Core request options
Authentication and target page
token: the API key issued by the service dashboard. Rolling a key revokes the previous key, so update every deployed secret before rotating.url: the public page to render. Pass the complete scheme, such ashttps://, and keep it as a parameter so Python performs encoding.
Render supplied HTML
Set custom_html to render supplied markup instead of loading the URL. This is useful for generating a receipt, previewing a component, or testing a small page without deploying it. Treat HTML as data: escape user-controlled content before inserting it, and keep large documents within the service’s current request limits.
import requests
html = """<!doctype html>
<html><body><h1>Invoice preview</h1><p>Paid</p></body></html>"""
params = {
"token": "YOUR_API_KEY",
"url": "https://example.com", # required by some client wrappers; custom_html takes precedence
"custom_html": html,
"output": "image",
"file_type": "png",
}
r = requests.get("https://shot.screenshotapi.net/v3/screenshot", params=params, timeout=60)
r.raise_for_status()
with open("invoice.png", "wb") as f:
f.write(r.content)
Hide elements with injected CSS
The css option injects CSS before capture. Hide cookie notices, navigation, or test-only controls without changing the source page:
params["css"] = ".module-content, .cookie-banner { display: none !important; }"
Use selectors that are stable across deployments. A selector matching nothing is not an API error; it simply leaves the page unchanged. If a site renders the element late, CSS alone may not remove a flash that occurs before the final capture.
Recommended Free Tools
Rank #2
Preserve login or other session state with cookies
Send cookies through the cookies option. The documented syntax is semicolon-separated, for example:
params = {
"token": "YOUR_API_KEY",
"url": "https://example.com/account",
"cookies": "session_id=abc123; region=us",
"output": "image",
"file_type": "png",
}
Use a short-lived, least-privileged session where possible. Never commit real session values to source control or log the complete query string. A cookie can expire, be scoped to another domain, or require additional anti-forgery state; a screenshot API cannot repair an invalid login.
Set browser geolocation
Supply numeric latitude and longitude values to establish the browser geolocation context. A page must actually request and use geolocation for the visual result to change; IP-based localization and server-side region checks are separate mechanisms.
params.update({
"latitude": "40.7128",
"longitude": "-74.0060",
})
Emulate client, language, and network origin
The following options shape what the destination sees:
user_agentrepresents a browser or device client.accept_languagessupplies the preferred language list.headerssends custom HTTP headers before rendering.proxyroutes the request through an address, with optional authentication, for regional or network-origin testing.
params.update({
"user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)",
"accept_languages": "fr-FR,fr;q=0.9",
"headers": "X-Preview: true",
"proxy": "http://user:[email protected]:8080",
})
These settings are independent. A French accept_languages value does not guarantee a French page if the application uses account settings or IP location; a proxy does not automatically set browser geolocation.
Putting options together
This example captures a logged-in, French-language page, hides a panel, sets coordinates, and saves WebP:
import requests
params = {
"token": "YOUR_API_KEY",
"url": "https://example.com/dashboard",
"output": "image",
"file_type": "webp",
"cookies": "session_id=REDACTED; consent=yes",
"css": ".sidebar, .newsletter-modal { display: none !important; }",
"latitude": "48.8566",
"longitude": "2.3522",
"user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/120 Safari/537.36",
"accept_languages": "fr-FR,fr;q=0.9",
"headers": "X-Screenshot-Run: nightly",
}
r = requests.get("https://shot.screenshotapi.net/v3/screenshot", params=params, timeout=60)
r.raise_for_status()
with open("dashboard.webp", "wb") as f:
f.write(r.content)
For repeatable tests, keep this configuration in version-controlled, non-secret data and inject the token, cookie, and proxy credentials through environment variables or a secret manager.
Equivalent calls in cURL and Node.js
cURL is useful for isolating Python code from API behavior:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
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
In Node.js, use URLSearchParams so the target URL is encoded correctly:
const q = new URLSearchParams({
token: 'YOUR_API_KEY',
url: 'https://example.com',
output: 'image',
file_type: 'png'
});
const res = await fetch(`https://shot.screenshotapi.net/v3/screenshot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const buffer = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('screenshot.png', buffer));
Choosing settings for common jobs
| Job | Recommended configuration | Important caveat |
|---|---|---|
| Visual regression | Fixed user_agent, language, cookies, CSS, and format |
Changing any of these can create intentional pixel differences. |
| Authenticated dashboard | Short-lived cookies, output=image |
Expired or domain-mismatched cookies produce a logged-out page. |
| Localized landing page | accept_languages, optional proxy, and coordinates if the page requests geolocation |
Language, IP region, and browser location can disagree. |
| Component prototype | custom_html, css, PNG |
External fonts or assets may not load unless reachable by the renderer. |
| Machine-readable diagnostics | output=JSON |
Do not write the JSON response directly to an image filename. |
Troubleshooting and reliable operation
401 or authentication errors
Check that the token is present, has no surrounding whitespace, and belongs to the account making the request. If a key was rolled, the previous key is revoked. Replace it in your secret store and redeploy.
400-level parameter errors
Verify spelling and capitalization, especially output=JSON, file_type, and the URL encoding. Start with only token, url, output=image, and file_type=png; add one option at a time.
The saved file is not a valid image
Inspect the HTTP status before writing bytes and temporarily request output=JSON for render information. An error document saved as .png is still just an error document. Keep the response headers and status in your application logs, but redact tokens, cookies, and proxy credentials.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Blank or partially rendered page
Confirm the URL is reachable from the service, not only from your laptop or private network. Check that required cookies and headers are included, and increase the client timeout for slow pages. If content appears after JavaScript runs, verify that the target page itself reaches a stable state; CSS cannot create content that never loads.
Wrong language, region, or account
Separate the causes: accept_languages affects language negotiation, proxy affects network origin, coordinates affect browser geolocation, and cookies affect session state. Test each in isolation and record the complete non-secret configuration.
Intermittent failures
Use bounded timeouts, retry only transient network or server responses, and apply exponential backoff with a limit. Do not blindly retry invalid credentials or malformed parameters. Store the URL, selected options, status, and a request identifier if supplied by the service so a failed capture can be reproduced.
Performance, security, and cost considerations
Rendering a full browser page is slower and heavier than downloading HTML. Reuse an HTTP session when making many Python requests, set a realistic timeout, and queue captures rather than launching unlimited concurrent calls. Smaller output formats reduce storage and transfer; PNG is preferable when exact pixels matter.
Keep API keys, cookies, authorization headers, and proxy credentials outside source code and logs. Grant a capture account only the access it needs, use expiring sessions, and delete captured files that contain personal or confidential data. The documented material specifies request options and examples but does not establish a universal latency, quota, uptime, or price figure; check your account’s current terms before budgeting a production workload.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
ScreenshotNeo provides a single-call website screenshot API and MCP server. Its clean-shot pipeline accepts cookie and consent banners, then removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result.
With an API key, this cURL request returns a WebP capture:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python and Node.js equivalents are:
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(`HTTP ${res.status}`);
const data = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', data));
See the ScreenshotNeo documentation for the full option set. It includes full-page and selector captures, dark mode, device presets and custom viewports, retina scale, PDFs, HTML/CSS rendering, custom JavaScript, clicks, waits, request blocking, headers, cookies, user agents, timezone and geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed links, asynchronous webhooks, bulk capture of 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. AI agents can use its MCP tools take_screenshot, get_page_info, and capture_pdf.
| Plan | Allowance and price |
|---|---|
| Free | 1,000 shots/month, no card |
| Starter | $5 for 3,000 shots |
| Growth | $15 for 15,000 shots |
| Pro | $39 for 60,000 shots |
| Scale | $99 for 250,000 shots |
| Business | $249 for 1,000,000 shots |
Every feature is included on every plan, and yearly billing gives two months free. Start with 1,000 free screenshots a month with no card, then move to a paid plan starting at $5 for 3,000 shots if your volume requires it.
FAQ
Does Python need a browser installed?
No. The Python program sends HTTP parameters to the hosted rendering endpoint; the browser work happens in the service.
Best Value
Can I keep the response in memory?
Yes. Use response.content for image or PDF bytes, then upload or process those bytes instead of writing a local file.
Which option changes the page source?
custom_html renders supplied markup and takes precedence over loading the target URL.
Can geolocation alone bypass regional restrictions?
No. Coordinates set browser geolocation. A site may instead use IP location, account settings, or another server-side rule; use the relevant proxy, cookies, or headers as well.
Frequently Asked Questions
Does Python need a browser installed?
No. The Python program sends HTTP parameters to the hosted rendering endpoint; the browser work happens in the service.
Can I keep the response in memory?
Yes. Use response.content for image or PDF bytes, then upload or process those bytes instead of writing a local file.
Which option changes the page source?
custom_html renders supplied markup and takes precedence over loading the target URL.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Can geolocation alone bypass regional restrictions?
No. Coordinates set browser geolocation. A site may instead use IP location, account settings, or another server-side rule; use the relevant proxy, cookies, or headers as well.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

