How to Send Custom Headers and Cookies to Browserless Screenshot API
Learn which headers reach Browserless and which reach the target site, then use Puppeteer through /function to set target headers or cookies before capture.
There are two different places to send headers when using Browserless Screenshot API:
- Client-to-Browserless headers belong on your HTTP request. For example,
Content-Type: application/jsontells Browserless that your request body is JSON. - Target-site headers and cookies must be configured in the browser before it navigates to the page. The current
/screenshotdocumentation does not show a body field for forwarding arbitrary headers or cookies to the target page.
For an ordinary screenshot, use the documented /screenshot endpoint. For custom browser setup, use Browserless /function to run Puppeteer code: set headers or cookies before page.goto(), then take and return the screenshot. Verify method signatures against the Puppeteer version in your Browserless environment before deploying. See the Screenshot API, Function API, and REST overview.
1. Decide which request needs the headers
| What you are configuring | Where it goes | Example |
|---|---|---|
| Your request to Browserless | HTTP client headers and query parameters | Content-Type: application/json; Browserless token |
| Browser navigation to the target site | Browser page or context before navigation | Authorization, tenant header, or a site cookie |
A header object in your client library only affects the HTTP request your program sends to Browserless. It does not, by itself, set headers on the browser navigation to example.com. Similarly, the Browserless API token authenticates your API call; it is not a cookie or authorization value for the site being captured.
2. Use the Screenshot API for a standard capture
The documented request is a POST to a regional production /screenshot endpoint. Put the Browserless token in the documented ?token= query parameter, send JSON, and save the binary image response. This example uses the SFO production host; use the region and endpoint appropriate for your account.
curl -X POST \
'https://production-sfo.browserless.io/screenshot?token=YOUR_API_TOKEN' \
-H 'Content-Type: application/json' \
-H 'Cache-Control: no-cache' \
-d '{"url":"https://example.com/","options":{"fullPage":true,"type":"png"}}' \
--output screenshot.png
Here, both HTTP headers are sent from cURL to Browserless. Neither is a target-page header configuration. The documented screenshot body includes the URL, screenshot options, style or script injection, and shared waiting/navigation/error configuration; it does not document a target headers or cookies property. Check the status and content type before treating the response as an image.
3. Set target headers or cookies with Browserless /function
Browserless /function runs custom Puppeteer code and supplies a page object. This is the documented route for a workflow that needs browser-level setup before navigation. The following is an illustrative pattern, not a Browserless-published recipe; confirm the supported Puppeteer version, function request format, and cookie method signatures in your deployment’s documentation.
Target headers
// Illustrative Puppeteer function body for Browserless /function.
// Confirm the deployed Puppeteer version and /function request format.
module.exports = async ({ page }) => {
await page.setExtraHTTPHeaders({
'Authorization': 'Bearer TARGET_SITE_TOKEN',
'X-Tenant': 'tenant-123'
});
await page.goto('https://example.com/private-report', {
waitUntil: 'networkidle0',
timeout: 60000
});
return await page.screenshot({ type: 'png', fullPage: true });
};
Set page headers before navigation so the initial document request receives them. Browser behavior for extra headers and subsequent requests can vary by Puppeteer version and request type; verify what your target site expects, especially for cross-origin navigations and redirects. Avoid logging bearer tokens.
Target cookies
// Illustrative Puppeteer function body. Verify cookie API for your version.
module.exports = async ({ page }) => {
await page.setCookie({
name: 'session',
value: 'TARGET_SESSION_VALUE',
domain: 'example.com',
path: '/',
secure: true,
httpOnly: true,
sameSite: 'Lax'
});
await page.goto('https://example.com/account', {
waitUntil: 'networkidle0',
timeout: 60000
});
return await page.screenshot({ type: 'png', fullPage: true });
};
Scope cookies to the intended domain and path, and use secure settings appropriate for the site. Keep session values secret. Setting document.cookie after navigation is not equivalent for every cookie: browser-managed properties such as HttpOnly cannot be set from page JavaScript, and the cookie would arrive too late for the first request.
Calling /function
Use the Function API’s currently documented request format and authentication for your region. Browserless supports token authentication in the query string for REST calls, and its Function/shared REST documentation also describes authorization-header authentication. The exact wrapper used to submit the function depends on the endpoint contract, so do not copy the following screenshot endpoint’s JSON body as if it were a /function recipe.
4. Headers, cookies, state, and waits
- API authentication: use the Browserless token as documented for the endpoint. Do not put a target site’s credential in place of this token.
- Target authentication: use browser-level request headers or a correctly scoped cookie in the Puppeteer workflow.
- Single capture: the simple
/screenshotendpoint is appropriate when its documented options cover the task. - Multi-step setup: choose
/functionwhen you need custom browser code before capture. - State across requests: Browserless REST calls are stateless; a later call does not automatically inherit the previous call’s cookies or page state. The REST overview points to BaaS sessions or persisted BrowserQL state for workflows that need persistence.
- Dynamic content: use documented wait controls or selector/event conditions when the page needs time to render. For long lazy-loaded pages, the Screenshot API FAQ recommends
scrollPage: true; combine it withoptions.fullPage: truewhen capturing the full page.
5. Check the response and diagnose failures
| Symptom | Likely cause | What to check |
|---|---|---|
| 401 or authorization error | Missing, invalid, or misplaced Browserless token | Confirm the token and endpoint authentication format. Keep Browserless credentials separate from target-site credentials. |
| Screenshot shows logged-out page | Target cookie/header was never set, was scoped incorrectly, or expired | Set it before navigation, check domain/path and expiry, and verify the target site’s expected authentication method. |
| 403, CAPTCHA, access denied, or blank result | The site may be blocking automation, or the target request may be denied | Inspect the target response and page. Browserless documents a separate /unblock API for supported bot-detection cases; custom cookies do not guarantee access. |
| 200 response but wrong or empty page | The API request succeeded while the target response failed or content was not ready | Inspect X-Response-Code from shared request configuration, and configure an appropriate wait or selector condition. |
| Missing images or lower-page content | Lazy-loaded resources did not run before capture | Use the documented scroll-page behavior and full-page option where appropriate. |
| Cookie method or option errors | The deployed Puppeteer version differs from the snippet’s assumptions | Check the Puppeteer version and current API signatures supported by the Browserless environment. |
| Login works once but not on the next call | REST requests do not preserve browser state between calls | Use a session-capable BaaS workflow or persisted BrowserQL state if persistence is required. |
The legacy BaaS v1 screenshot documentation is marked deprecated and no longer actively supported. Use current REST documentation for new cloud integrations.
6. Performance, reliability, and cost considerations
- Use
/screenshotfor the smallest setup when no target-specific browser configuration is needed. A custom/functionworkflow adds code and version compatibility to maintain. - Wait only for the condition your page needs. A broad network-idle wait can take longer on pages with persistent requests; a specific selector or event can make the completion condition clearer.
- Large full-page captures and pages with many images take more browser work and produce larger responses. Use only the capture dimensions and output format the downstream task needs.
- REST state is per request. For repeat authenticated captures, plan explicitly for session persistence rather than assuming cookies survive between API calls.
- Browserless pricing and resource limits depend on the current account and plan; consult the official plan details before estimating production cost. No fixed latency or success-rate figure is implied here.
7. Or skip the browser setup
If you need a screenshot without writing and maintaining a Puppeteer setup, ScreenshotNeo is a website screenshot API and MCP server. Its API options include custom headers, cookies, and Authorization, alongside waits, viewport and device settings, full-page capture, and other capture controls. See the ScreenshotNeo API documentation.
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}`);
ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before the shot. Bot checks, blank pages, failed loads, and cache hits are never billed, and response headers say which page verdict occurred and whether it was billed. Its MCP server lets AI agents use screenshot and page information tools. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo free: 1,000 screenshots a month, no card required.
FAQ
Can I add a target-page headers field to the /screenshot JSON?
The current Screenshot API documentation does not document a target-page headers or cookies field. Use the documented endpoint for its supported options, or /function for custom Puppeteer setup.
Does the Browserless token log the target website in?
No. It authenticates your request to Browserless. The target site needs its own browser-level credentials.
Can I reuse cookies automatically on my next REST call?
No. REST calls are stateless. Use a session-capable or persisted-state workflow when later requests need the same browser session.
Should I use the old BaaS v1 screenshot endpoint?
Only when maintaining a legacy integration that already depends on it. Its documentation is deprecated; use current REST guidance for new work.


