How to Send Custom Headers to a Website Screenshot API
Learn how screenshot APIs send custom headers to the target website, how to keep credentials separate, and how to troubleshoot authentication failures.
To send a custom header to the website being captured, set it in the screenshot provider’s target-browser or rendering options. Do not assume that a header on your request to the screenshot service will be forwarded to the target website: those are two separate HTTP contexts, with separate credentials and purposes.
The exact option name is provider-specific. For example, Screenshot API documents a repeatable header GET parameter and a POST headers object; Cloudflare Browser Run documents setExtraHTTPHeaders in its JSON request body. The examples below follow the published documentation for those providers. [Screenshot API documentation] [Cloudflare Browser Run screenshot documentation]
1. Separate the two sets of headers
A screenshot request involves two requests:
- Your client to the screenshot API. Its headers or parameters authenticate you with the provider.
- The provider’s browser to the target website. Its headers are used by the site you want to capture, for example to authorize access to a preview page.
Putting a target-site token in the outer request’s Authorization header does not necessarily send that token to the page. Configure it using the provider’s documented target-header option. Keep the provider API key and target-site credential separate.
| Purpose | Sent by | Typical example |
|---|---|---|
| Authenticate the screenshot API request | Your application or command line | Authorization: Bearer YOUR_SCREENSHOT_API_KEY |
| Authenticate the page being captured | The screenshot provider’s browser | Authorization: Bearer TARGET_SITE_TOKEN |
2. Choose the authentication mechanism the page expects
Before adding a header, check how the target site expects the browser to authenticate. Use the matching mechanism:
- Custom token or preview header: use the provider’s arbitrary target-header option.
- Session-based login: use the provider’s cookie option if available, with the cookie name, value, and scope required by the site.
- HTTP Basic Authentication: use a provider’s Basic Auth option if it offers one. Cloudflare documents Basic Auth separately from custom headers.
Do not assume an API-key authentication example proves that a provider can set arbitrary headers on target-page requests. Screenshot API’s documentation describes caller authentication and locale-based Accept-Language; the reviewed parameter list does not establish general custom target-header support. Verify the provider’s current reference if arbitrary target headers are required. [Screenshot API documentation]
3. Send target-page headers with Screenshot API
Screenshot API documents header as a repeatable GET parameter using the format Name: value. Its POST endpoint accepts a headers object. Use the endpoint and parameters shown in the provider’s documentation for your account and capture format.
One target header with cURL
curl -G 'https://screenshot-api.net/v1/screenshot' \
-H 'Authorization: Bearer YOUR_SCREENSHOT_API_KEY' \
--data-urlencode 'url=https://example.com/protected-page' \
--data-urlencode 'header=Authorization: Bearer TARGET_SITE_TOKEN' \
-o shot.png
The first Authorization header authenticates your request to Screenshot API. The header parameter asks its browser to send a different authorization value to the target page.
Multiple target headers with cURL
Repeat the header parameter once per target header. Keep each value in the documented Name: value form:
curl -G 'https://screenshot-api.net/v1/screenshot' \
-H 'Authorization: Bearer YOUR_SCREENSHOT_API_KEY' \
--data-urlencode 'url=https://preview.example.com/dashboard' \
--data-urlencode 'header=x-preview-token: TARGET_SITE_TOKEN' \
--data-urlencode 'header=X-Tenant: example-team' \
-o dashboard.png
Put credentials in a POST body
Screenshot API advises using POST for credentials because query strings can be recorded in access logs. Its documented POST form accepts a JSON headers object:
curl -X POST 'https://screenshot-api.net/v1/capture' \
-H 'Authorization: Bearer YOUR_SCREENSHOT_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://preview.example.com/dashboard",
"headers": {
"x-preview-token": "TARGET_SITE_TOKEN",
"X-Tenant": "example-team"
}
}'
Confirm the response format for that endpoint before saving the response as an image. This example shows the documented request shape; it does not assume a response format not specified here.
Send headers from Python
This example uses requests to make the documented GET request, repeat the target-header parameter, and save the returned image. Install the dependency with python -m pip install requests. For real credentials, prefer a provider’s documented POST form where available.
import os
import requests
api_key = os.environ["SCREENSHOT_API_KEY"]
target_token = os.environ["TARGET_SITE_TOKEN"]
response = requests.get(
"https://screenshot-api.net/v1/screenshot",
headers={"Authorization": f"Bearer {api_key}"},
params=[
("url", "https://example.com/protected-page"),
("header", f"Authorization: Bearer {target_token}"),
("header", "X-Tenant: example-team"),
],
timeout=90,
)
response.raise_for_status()
content_type = response.headers.get("Content-Type", "")
if not content_type.startswith("image/"):
raise RuntimeError(f"Expected an image response, got {content_type!r}")
with open("shot.png", "wb") as image_file:
image_file.write(response.content)
Set SCREENSHOT_API_KEY and TARGET_SITE_TOKEN in your environment before running the script. Avoid printing either value in logs.
Send headers from Node.js
This runnable example uses Node.js’s built-in fetch. It appends each target header as a separate query parameter and writes the image response to a file. Query parameters can be logged, so for credentials use the provider’s documented POST method instead where available.
import { writeFile } from "node:fs/promises";
const apiKey = process.env.SCREENSHOT_API_KEY;
const targetToken = process.env.TARGET_SITE_TOKEN;
if (!apiKey || !targetToken) {
throw new Error("Set SCREENSHOT_API_KEY and TARGET_SITE_TOKEN");
}
const params = new URLSearchParams();
params.set("url", "https://example.com/protected-page");
params.append("header", `Authorization: Bearer ${targetToken}`);
params.append("header", "X-Tenant: example-team");
const response = await fetch(
`https://screenshot-api.net/v1/screenshot?${params}`,
{ headers: { Authorization: `Bearer ${apiKey}` } },
);
if (!response.ok) {
throw new Error(`Screenshot API returned HTTP ${response.status}`);
}
const contentType = response.headers.get("content-type") ?? "";
if (!contentType.startsWith("image/")) {
throw new Error(`Expected an image response, got ${contentType}`);
}
await writeFile("shot.png", Buffer.from(await response.arrayBuffer()));
Use a current Node.js version with built-in fetch. The API key authenticates the service request; the target token is part of the provider-specific rendering option.
4. Send target-page headers with Cloudflare Browser Run
Cloudflare’s screenshot endpoint documents target-page headers in the JSON request body under setExtraHTTPHeaders. The outer bearer token authenticates to Cloudflare; the nested value is intended for the target page.
curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-run/screenshot' \
-H 'Authorization: Bearer <CLOUDFLARE_API_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com/protected-page",
"setExtraHTTPHeaders": {
"Authorization": "Bearer <TARGET_SITE_TOKEN>"
}
}' \
--output screenshot.png
Replace the placeholders with your account ID and credentials. Cloudflare also documents separate mechanisms for session cookies and HTTP Basic Authentication. Use one of those when it matches the page’s login flow instead of forcing credentials into a custom-header field. [Cloudflare screenshot endpoint documentation]
5. Keep credentials out of logs and source code
- Prefer a documented POST JSON body for target credentials when the provider supports it.
- Do not commit API keys or target tokens to source control. Load them from environment variables or your secret manager.
- Do not log full request URLs when they contain a token in a query parameter.
- Use credentials scoped to the specific preview or page when your target service supports limited credentials.
- Do not put your screenshot provider’s API key inside the target-page header option, or the target token in the outer provider-authentication header.
POST bodies reduce exposure through URL access logs, but they do not make a secret safe to disclose in application logs, error reports, or source code. Handle both credentials as secrets.
6. Check whether the target accepted the header
A successful screenshot API response only means the capture request produced a response; the browser might have rendered a login, access-denied, or error page. Inspect the image and, when the provider exposes it, the final page status. Screenshot API documents an X-Page-Status response header for the final document status. [Screenshot API documentation]
- Request the same page in a normal browser using the intended authentication mechanism.
- Check the exact header name and value format the target expects, including the bearer prefix if required.
- Confirm you set the header through the screenshot provider’s target-page option.
- Check the rendered result and final page status for a login page, redirect, or access-denied response.
- If the target relies on session state, use its cookie or Basic Auth mechanism where supported.
Common errors and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| The capture shows a login page | The target token is missing, expired, malformed, or sent in the wrong request context. | Check the target’s expected authentication scheme and configure the credential using the provider’s target-header, cookie, or Basic Auth option. |
| The provider says the API key is invalid | The provider credential is missing or was placed in the target-page option. | Send the provider key using that provider’s documented outer authentication method. |
| Only one of several headers reaches the target | The provider expects a repeatable parameter, a JSON object, or a different field name. | Follow that provider’s syntax exactly. For Screenshot API GET, repeat header; for its POST form, use the headers object. |
Adding Authorization has no effect |
The page may rely on a session cookie or Basic Auth, or the provider may not support arbitrary target headers. | Use the matching documented authentication feature; confirm arbitrary target-header support before relying on it. |
| The image file contains JSON or an error document | The endpoint returned an API error or a non-image response. | Check the HTTP status and Content-Type before saving bytes as an image. Read the provider’s documented error response. |
| The token appears in application or proxy logs | A secret was placed in a query string or a request was logged in full. | Use a POST body when documented, redact credentials, and avoid logging full URLs. |
| The page status is successful but the screenshot is wrong | The page may render an application-level denial or redirect despite a successful document response. | Inspect the screenshot itself and follow redirects or application state as appropriate; a successful HTTP status alone does not prove authorization worked. |
Performance, reliability, and cost considerations
Custom headers mainly affect authentication and routing. They do not guarantee that the page will finish rendering, that client-side code will accept the session, or that every page resource uses the same request context. Treat the rendered result as the final check, and use the provider’s documented wait options when a protected page renders asynchronously.
- Reliability: expired tokens, redirects, cookies, and application-level access checks can produce a valid screenshot of the wrong page. Check both image content and available page-status metadata.
- Security: a GET query string may be retained in logs. Prefer POST for secrets when available, and keep both provider and target credentials out of logs and code.
- Cost: provider pricing and billing behavior differ. Check the selected service’s current pricing and whether failed captures are billable; the source documentation cited here does not establish a general cost rule across providers.
Or skip the browser setup
With ScreenshotNeo, make one GET request to capture a page. Its API accepts custom headers, cookies, and Authorization for the target page. See the ScreenshotNeo API documentation for the available parameters and response behavior.
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,
)
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}`);
Add target headers using ScreenshotNeo’s documented header parameter; the call above shows the basic one-request capture shape. Cookie banners, popups, and chat widgets are removed 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; paid plans start at $5 for 3,000.
Sign up for ScreenshotNeo and get 1,000 free screenshots a month, with no card required.
FAQ
Can I reuse the same header option across screenshot APIs?
No. Providers use different field names and request formats. Check the provider’s documentation for the browser-side header mechanism.
Should I send authentication as a header, cookie, or Basic Auth?
Use the method the target website expects. A session login commonly depends on cookies; a site configured for HTTP Basic Authentication should use that mechanism when the provider supports it.
Does an image response prove the target accepted my credentials?
No. The screenshot may depict a login or denial page. Inspect the image and any available final page status.
Is an outer Authorization header forwarded to the captured site?
Do not assume it is. Set target-site credentials with the provider’s target-browser option and keep them separate from the provider API key.
Sources
- Screenshot API documentation — target headers through repeatable GET parameters or a POST JSON object, and its guidance about credentials in query strings.
- Cloudflare Browser Run screenshot endpoint — target headers through
setExtraHTTPHeaders, plus separate cookie and Basic Auth mechanisms. - Screenshot API documentation — caller authentication and locale options; the reviewed parameter list does not establish arbitrary target headers.


