ScreenshotNeo

BlogHow-to

How to Use Screenshotlayer with Python Requests

Send Screenshotlayer capture requests with Python, set screenshot options, save image responses safely, and troubleshoot common API errors.

By the ScreenshotNeo team4 October 20268 min read

Use Python Requests to send a GET request to Screenshotlayer’s capture endpoint, passing your access key and a fully qualified target URL in the params dictionary. Check the response before saving it: an API error payload is not a screenshot.

import os
from pathlib import Path

import requests

endpoint = "https://api.screenshotlayer.com/api/capture"
params = {
    "access_key": os.environ["SCREENSHOTLAYER_ACCESS_KEY"],
    "url": "https://example.com",
    "fullpage": "1",
    "viewport": "1440x900",
    "format": "PNG",
}

response = requests.get(endpoint, params=params, timeout=60)
response.raise_for_status()

content_type = response.headers.get("content-type", "")
if not content_type.startswith("image/"):
    raise RuntimeError(
        f"Expected image response, received {content_type!r}: {response.text}"
    )

Path("screenshot.png").write_bytes(response.content)
print("Saved screenshot.png")

Install the dependency with python -m pip install requests. Set SCREENSHOTLAYER_ACCESS_KEY in your environment before running the script. The sample is an integration pattern based on the published endpoint and parameters; it has not been run against an account. Confirm current response behavior in the Screenshotlayer API documentation.

1. Get an access key and prepare the request

  1. Create or sign in to a Screenshotlayer account and find or reset the access key in its account dashboard.
  2. Keep the key in an environment variable or server-side secret store. Do not commit it to source control or expose it in browser-side JavaScript.
  3. Pass the required access_key and url parameters. The URL must include its protocol, such as https://.
  4. Use HTTPS for the API endpoint only if your account plan supports it; the provider describes HTTPS as a paid-plan feature. Check current plan terms.

Requests’ params argument handles query-string encoding, including target URLs with their own query strings. Avoid building the request URL by concatenating strings.

2. Configure the capture

Send options as query parameters alongside the required credentials. The documented options include:

Parameter Use Notes
access_key Authenticates the account. Required. Treat it as a secret.
url Chooses the page to capture. Required, with http:// or https://.
fullpage Requests a full-height screenshot. Set to 1.
viewport Sets browser viewport dimensions. The documented default is 1440x900.
width Requests a thumbnail width in pixels. Check the current spec for supported values and interactions with other sizing options.
format Chooses output format. PNG is the documented default. The FAQ lists PNG, JPEG, and GIF; WebP is advertised on the pricing page for paid plans. Confirm account eligibility before relying on a format.
delay Waits before capture. Useful for animations or effects that need time to finish; it adds that wait to request latency.
ttl Controls cache lifetime, in seconds. The specification lists 2,592,000 seconds (30 days) as the default. The FAQ says a custom TTL can be lower.
force Requests a fresh capture. Use when a cached image would be stale; confirm current parameter semantics in the API spec.
css_url Applies a stylesheet by URL. Use a reachable stylesheet URL and verify its access and loading behavior.
placeholder Customizes the loading placeholder. See the current API specification for accepted values.
user_agent, accept_lang Customizes browser user agent or accepted language. Useful when the page varies by these request attributes.
secret_key Optional provider parameter. Consult the provider documentation for its exact purpose and generation rules.
export Exports captures using custom FTP or AWS S3 details. Review the API docs for required export fields and account support; protect destination credentials.

Use strings for numeric or boolean-like query values when convenient; Requests encodes them into the query string. For example, add "delay": "3" or "width": "600" to params. Don’t assume undocumented combinations of width, viewport, fullpage, and format—check the provider spec and inspect the returned image dimensions.

3. Handle errors and save only image responses

The documented API error structure includes success: false and an error object with a code, type, and explanatory info. The public materials reviewed do not fully establish all current HTTP status-code, MIME-type, or streaming conventions. Therefore, check HTTP errors, then verify that the body is an image before writing it to a file.

For a safer diagnostic variant, catch HTTP failures and avoid printing the access key, which is present in the request URL:

import os
from pathlib import Path

import requests

endpoint = "https://api.screenshotlayer.com/api/capture"
params = {
    "access_key": os.environ["SCREENSHOTLAYER_ACCESS_KEY"],
    "url": "https://example.com",
    "format": "PNG",
}

try:
    response = requests.get(endpoint, params=params, timeout=(10, 60))
    response.raise_for_status()
except requests.Timeout as exc:
    raise RuntimeError("Screenshotlayer request timed out") from exc
except requests.HTTPError as exc:
    # Do not log response.request.url: it can contain the access key.
    detail = exc.response.text[:1000] if exc.response is not None else ""
    raise RuntimeError(f"Screenshotlayer returned an HTTP error: {detail}") from exc
except requests.RequestException as exc:
    raise RuntimeError("Could not reach Screenshotlayer") from exc

content_type = response.headers.get("content-type", "")
if not content_type.lower().startswith("image/"):
    # Error responses may contain account or request details; review before logging.
    raise RuntimeError(
        f"Expected an image, received {content_type!r}: {response.text[:1000]}"
    )

Path("screenshot.png").write_bytes(response.content)

The timeout tuple sets separate connection and read limits. Increase the read timeout only when your capture needs it; use a bounded timeout rather than waiting forever. For large responses, Requests can stream the body, but the reviewed Screenshotlayer materials do not specify a streaming recommendation. If you use streaming, still validate status and content type before writing chunks.

4. Troubleshoot common problems

Symptom Likely cause What to do
Missing or invalid access key The key is absent, misspelled, reset, or belongs to a different account. Check the dashboard, reset if needed, and confirm the environment variable is set in the process running Python.
Usage limit reached The account has exhausted its snapshot allowance. Check account usage and plan quota. Don’t retry the same request in a tight loop; retrying does not resolve an exhausted quota.
Invalid URL The target is malformed or lacks a protocol. Pass a full URL such as https://example.com/path and confirm the destination is reachable.
Saved file is JSON or text The API returned an error payload that code saved as if it were an image. Check status, content type, and the provider’s error object before saving.
Read timeout The capture or target page took longer than the client’s read timeout. Check target availability, choose a suitable bounded timeout, and avoid immediately repeating many identical requests.
Unexpectedly old image A cached capture may still be within its TTL. Review ttl and the documented force option; request a fresh capture when appropriate.
Missing animation or late content The page was captured before that content appeared. Try a documented delay, while accounting for the added latency. A delay cannot fix content that never loads.
HTTPS endpoint unavailable for account HTTPS API access may not be included in the account’s current plan. Confirm current plan eligibility and endpoint requirements with Screenshotlayer before changing transport.

5. Performance, reliability, and cost

  • Latency: Each call waits for the remote API and target page capture. A larger delay or full-page capture can increase waiting and response size. Set a realistic timeout and process independent URLs concurrently only within your account’s allowed capacity.
  • Retries: Retry only transient network failures, with a small retry limit and backoff. Do not retry authentication, invalid-URL, or quota errors unchanged. Be mindful that repeat requests may affect usage according to the provider’s current billing rules.
  • Caching: The documented default TTL is 30 days. Set a shorter TTL when freshness matters, or use the documented force option for a fresh capture. Confirm exact cache behavior in current docs.
  • Reliability: Treat a capture as an external dependency: set timeouts, validate responses, log a redacted request identifier or target host, and surface failures clearly. The provider states uptime is “around 99.9%,” but says it does not publish public statistics; this is a vendor statement, not independently verified uptime.
  • Cost: The FAQ lists 100 snapshots per month on the free plan and paid plans starting at USD 19.99 monthly. The pricing page lists plan-specific volume and features and says overage fees may apply. These terms can change; confirm current quotas, HTTPS, formats, concurrency, export access, commercial-use permission, and overages on the Screenshotlayer pricing page before choosing a plan.

6. cURL, Python, and Node.js examples

The same basic request can be made from other clients. Use your own access key and target URL, and verify the returned response before treating it as an image.

cURL

curl -G "https://api.screenshotlayer.com/api/capture" \
  --data-urlencode "access_key=$SCREENSHOTLAYER_ACCESS_KEY" \
  --data-urlencode "url=https://example.com" \
  --data-urlencode "fullpage=1" \
  --data-urlencode "viewport=1440x900" \
  --data-urlencode "format=PNG" \
  -o screenshot.png

Because a direct -o saves any response body, inspect the response headers and file when diagnosing errors rather than assuming the output is a valid image.

Python Requests

import os
import requests

response = requests.get(
    "https://api.screenshotlayer.com/api/capture",
    params={
        "access_key": os.environ["SCREENSHOTLAYER_ACCESS_KEY"],
        "url": "https://example.com",
        "width": "600",
        "format": "JPG",
    },
    timeout=60,
)
response.raise_for_status()
if not response.headers.get("content-type", "").lower().startswith("image/"):
    raise RuntimeError("API returned a non-image response")
with open("thumbnail.jpg", "wb") as output:
    output.write(response.content)

Node.js

const params = new URLSearchParams({
  access_key: process.env.SCREENSHOTLAYER_ACCESS_KEY,
  url: 'https://example.com',
  fullpage: '1',
  viewport: '1440x900',
  format: 'PNG',
});

const response = await fetch(
  `https://api.screenshotlayer.com/api/capture?${params}`,
  { signal: AbortSignal.timeout(60000) }
);
if (!response.ok) {
  throw new Error(`Screenshotlayer returned HTTP ${response.status}`);
}
const contentType = response.headers.get('content-type') || '';
if (!contentType.toLowerCase().startsWith('image/')) {
  throw new Error(`Expected image response, received ${contentType}`);
}
const image = Buffer.from(await response.arrayBuffer());
await import('node:fs/promises').then(({ writeFile }) => writeFile('screenshot.png', image));

Keep credentials in server-side environment variables in all three examples. Query-string credentials can appear in request logs, so redact URLs in logs and avoid exposing these calls to untrusted clients.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. Its API returns a screenshot or PDF from one GET request; see the ScreenshotNeo API documentation for available parameters and setup.

import requests

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

ScreenshotNeo removes cookie banners, popups, and chat widgets before the shot. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.

Frequently asked questions

How do I get an API access key?

Screenshotlayer says registered users can find or reset the key in the account dashboard. Store it as a secret and do not publish it.

Can I request a thumbnail?

The API documents a width parameter for thumbnail width in pixels. Check the current specification for its supported range and how it combines with viewport settings.

Can I wait for animations before capture?

The documented delay parameter waits a number of seconds before capture. It can accommodate effects that need extra time, but increases response latency.

Does Screenshotlayer support WebP?

The pricing page advertises WebP for paid plans, while the FAQ lists PNG, JPEG, and GIF. Confirm current format support for your account before depending on WebP.