Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Pass headers to the screenshot provider as rendering options, not as headers on your own call to the provider. For ScreenshotOne, add one URL-encoded headers parameter for each target-page header, for example headers=Authorization: Bearer TOKEN and headers=X-API-Key: key. For larger or more sensitive payloads, send the same options as JSON in a POST request. The provider then applies those headers inside the browser that loads the target page.

What a custom header actually does

A screenshot request has two different HTTP conversations:

  1. Your application calls the screenshot service and authenticates with that service’s access key or token.
  2. The service’s browser requests the target URL and renders the response into an image or PDF.

A header added to conversation one is not automatically forwarded to conversation two. Put target-page headers in the provider’s documented rendering option. This distinction explains why adding -H "Authorization: ..." to a request sent to the screenshot API often fails to authenticate the page.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use a target header when the page expects bearer authentication, an API key, tenant or request ID, a preview flag, or another server-side value. Treat both your screenshot-service credential and the target-page credential as secrets.

ScreenshotOne: GET with one or more headers

ScreenshotOne expresses a header as Header-Name:Header-Value. Repeat the headers query parameter for additional headers. Encode spaces, colons, and other reserved characters before sending the URL.

https://api.screenshotone.com/take?access_key=ACCESS_KEY&url=https%3A%2F%2Fexample.com&headers=Authorization%3A%20Bearer%20TOKEN&headers=X-Request-ID%3A%20123

The example sends two headers to example.com: an Authorization bearer token and an X-Request-ID. Do not concatenate multiple headers into one value; each header gets its own repeated parameter.

cURL

curl -G "https://api.screenshotone.com/take" 
  --data-urlencode "access_key=$SCREENSHOTONE_ACCESS_KEY" 
  --data-urlencode "url=https://example.com/account" 
  --data-urlencode "headers=Authorization: Bearer $TARGET_TOKEN" 
  --data-urlencode "headers=X-API-Key: $TARGET_API_KEY" 
  -o account.png

--data-urlencode prevents a space in Bearer TOKEN, a colon in a header, or characters in the page URL from corrupting the query string. Keep values in environment variables rather than shell history or source code.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Python

import os
import requests

params = [
    ("access_key", os.environ["SCREENSHOTONE_ACCESS_KEY"]),
    ("url", "https://example.com/account"),
    ("headers", f"Authorization: Bearer {os.environ['TARGET_TOKEN']}"),
    ("headers", f"X-API-Key: {os.environ['TARGET_API_KEY']}"),
]
response = requests.get("https://api.screenshotone.com/take", params=params, timeout=90)
response.raise_for_status()
with open("account.png", "wb") as image:
    image.write(response.content)

Using a list of tuples preserves duplicate headers keys. A dictionary cannot represent two values for the same key reliably.

Node.js

const accessKey = process.env.SCREENSHOTONE_ACCESS_KEY;
const targetToken = process.env.TARGET_TOKEN;
const targetApiKey = process.env.TARGET_API_KEY;
const params = new URLSearchParams();
params.set('access_key', accessKey);
params.set('url', 'https://example.com/account');
params.append('headers', `Authorization: Bearer ${targetToken}`);
params.append('headers', `X-API-Key: ${targetApiKey}`);
const response = await fetch(`https://api.screenshotone.com/take?${params}`);
if (!response.ok) throw new Error(`Screenshot failed: ${response.status}`);
const data = Buffer.from(await response.arrayBuffer());
require('node:fs').writeFileSync('account.png', data);

Authenticated pages: Authorization, X-API-Key, and cookies

Bearer Authorization

The documented form is headers=Authorization: Bearer <your authentication token>. The token is sent to the target page, not used as the screenshot service’s access_key.

https://api.screenshotone.com/take?access_key=<your access key>&url=https://example.com&headers=Authorization:%20Bearer%20<your authentication token>

ScreenshotOne also documents an authorization=Bearer <token> option. Prefer the provider’s header syntax when you need several custom headers or want the exact wire representation.

X-API-Key

Send an API key as headers=X-API-Key: YOUR_KEY. Header names are case-insensitive, but the spelling and expected value format must match the target application’s contract.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Cookie-authenticated applications

If the application authenticates with a session cookie, supply the cookie through the provider’s cookie option instead of inventing an Authorization header. A site can require both a cookie and a custom header; configure both and verify that the session is valid for the requested host.

Precedence and overrides

ScreenshotOne states: “Headers can override all other previously implicitly set headers by options like cookies or authorization.” This matters when you set the same credential in two places: the explicit header can win, producing a different result from the cookie or authorization option.

When POST JSON is the safer integration

GET is convenient for short URLs and simple jobs, but query strings can expose credentials in logs, traces, browser history, and proxy records. Use POST JSON when the option set is large, when you send HTML or Markdown, or when you want secrets out of the URL. ScreenshotOne documents a maximum POST body size of 100 MiB.

curl -X POST "https://api.screenshotone.com/take" 
  -H "Content-Type: application/json" 
  -d '{
    "access_key": "ACCESS_KEY",
    "url": "https://example.com/account",
    "headers": [
      "Authorization: Bearer TARGET_TOKEN",
      "X-API-Key: TARGET_KEY"
    ]
  }' 
  -o account.png

Confirm the current POST schema in the provider’s documentation before shipping: providers differ on whether headers are an array, object, or repeated field. Never log the complete JSON body if it contains credentials.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Browserless: headers inside a POST screenshot job

Browserless exposes a POST /screenshot REST endpoint. Its service token is a query parameter; the request body is JSON containing the target URL and an options object. The response can be PNG, JPEG, or WebP according to the selected type.

curl -X POST 'https://production-sfo.browserless.io/screenshot?token=YOUR_API_TOKEN' 
  -H 'Content-Type: application/json' 
  -d '{"url":"https://example.com/","options":{"fullPage":true,"type":"png"}}' 
  --output screenshot.png

Browserless also documents launch parameters for REST calls to /screenshot, /pdf, /content, and /scrape. Check its current API reference for the exact location and shape of a custom-header option before implementing it; do not assume ScreenshotOne’s repeated query syntax applies to Browserless.

Designing a reliable header-enabled capture

Encode and validate

  • URL-encode the target URL and every header value in a GET request.
  • Preserve repeated keys; use a tuple list in Python and append in JavaScript.
  • Reject newline characters in header names and values to prevent request splitting.
  • Allow only headers your application explicitly needs. Do not forward a browser’s entire header dump.

Protect credentials

  • Read provider keys and target credentials from environment variables or a secrets manager.
  • Prefer POST when long-lived credentials would otherwise appear in query logs.
  • Use narrowly scoped, short-lived target tokens where the target system supports them.
  • Redact Authorization, API-key, Cookie, and Set-Cookie values from application logs and error reports.

Make the page deterministic

Authentication alone does not guarantee the desired image. The page may redirect to a login screen, render after JavaScript, or require a tenant header. Configure the provider’s documented wait, viewport, full-page, script, style, and resource settings as needed. Keep a non-secret request ID in the headers so you can correlate a failed capture with server logs.

Common failures and fixes

The screenshot shows a login page

Cause: the header was sent to the screenshot service rather than the target browser, the token is expired, or the target redirects to another host. Fix: put the credential in the provider’s rendering option, check the redirect chain, and issue a token valid for the final host and path.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Only the first custom header arrives

Cause: duplicate query keys were collapsed by a dictionary, framework, or proxy. Fix: use repeated headers parameters and verify the final encoded URL; in Python use tuples and in Node use params.append.

401 or 403 despite a valid credential

Cause: wrong scheme, missing tenant or API-key header, cookie-only authentication, an IP allow-list, or a token scoped to a different audience. Fix: reproduce the target request with the same method and headers outside the screenshot service, then add only the required values to the capture.

Malformed URL or unexpected header value

Cause: an unescaped space, colon, ampersand, or percent sign changed query parsing. Fix: use --data-urlencode, a URL-parameter library, or URLSearchParams; never hand-concatenate secrets.

GET works locally but fails in production

Cause: production logs, gateways, or WAF rules reject long URLs or expose credentials. Fix: switch to POST JSON, shorten the option set, and update secret-redaction rules.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Capture times out or is blank

Cause: the authenticated page depends on a delayed API call, a blocked third-party resource, or a challenge page. Fix: add the provider’s documented wait condition or delay, test the page without the screenshot service, and inspect the provider’s status and error response. A credential cannot solve a page that never finishes rendering.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Choosing an API approach

Need Practical choice Reason
One URL and a few headers ScreenshotOne GET Readable request and repeated headers parameters.
Many options, HTML/Markdown, or less secret exposure ScreenshotOne POST JSON body and documented 100 MiB maximum.
Existing browser-automation stack Browserless POST JSON screenshot jobs and separate launch parameters.
Need a managed API with clean captures and predictable billing ScreenshotNeo Cookie and popup handling, only clean shots billed, and a $5 paid entry plan.

Compare providers on header expression, service authentication, target-page authentication, browser controls, output formats, errors, rate limits, caching, and total cost. Limits and syntax can change, so verify the live provider documentation before release.

Or skip the browser setup

ScreenshotNeo accepts custom headers directly while it loads the target page. It also accepts cookies, user agents, Authorization, wait rules, scripts, CSS, device settings, full-page capture, and PDF options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for the header option and the other capture parameters. Cookie banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and each response identifies the page verdict and billing result with X-Page-Verdict and X-Billed headers. Its MCP server lets Claude, Cursor, and other MCP clients call take_screenshot, get_page_info, and capture_pdf. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Sign up free.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Operational checklist

  • Confirm the target’s exact authentication mechanism and final redirect host.
  • Put target headers in rendering options, not only in client request headers.
  • Encode every GET value and preserve duplicate header parameters.
  • Use POST for large payloads or sensitive, long-lived values.
  • Keep provider and target credentials out of source control, URLs, and logs.
  • Test success, expired-token, redirect, blank-page, timeout, and rate-limit cases.
  • Record non-secret request IDs and provider response headers for diagnosis.

Frequently Asked Questions

Can I send an Authorization header and an API key together?

Yes. Send each as its own documented header option; with ScreenshotOne, repeat the headers query parameter.

Does a header on my cURL request automatically reach the website?

No. It authenticates your call to the screenshot service unless that service explicitly maps it to the target browser request.

Should I use a cookie or an Authorization header?

Use the mechanism the target application requires. Cookie sessions need cookies; bearer-token APIs need Authorization. Some applications require both.

Is GET or POST more secure for credentials?

POST keeps long values out of the query string, but you still need HTTPS, secret redaction, and careful request-body logging.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The Bottom Line

Define custom headers in the screenshot provider’s browser-rendering options, encode them correctly, and preserve one parameter per header. Use POST for larger or more sensitive jobs, test redirects and authentication failures, and keep every credential private.

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.