ScreenshotNeo

BlogHow-to

How to Take Authenticated Website Screenshots with Browserless

Save a completed Browserless login as an authenticated profile, then reuse it for screenshots. Includes REST, BrowserQL, session options, code, and troubleshooting.

By the ScreenshotNeo team4 October 20268 min read

To take an authenticated website screenshot with Browserless, save the browser state after you finish logging in, then send a POST request to its /screenshot endpoint with the target URL and saved profile name. Browserless restores the profile before the page renders. This lets repeat captures reuse a login without automating the login flow for every screenshot. For interactive logins or pages that need extra clicks and waits, use a connected browser session instead. Browserless authenticated profiles store cookies, localStorage, and IndexedDB; they do not store sessionStorage. [Profile documentation]

Choose the right authentication method

Situation Method Important detail
Repeat screenshots behind a normal web-app login Save and reuse an authenticated profile Wait for the final login redirect and signed-in state before saving.
Login requires several interactions, navigation steps, or page-specific waits Keep a browser session open and automate it Perform the interaction before capturing, then close the session when finished.
HTTP Basic or proxy authentication challenge BrowserQL authenticate mutation This handles HTTP challenges, not a website’s interactive login form.
You already have valid cookie values BrowserQL cookies mutation Cookie domain, path, Secure, and SameSite rules still apply.

For most recurring captures, profiles are the shortest path. Browserless scopes profiles to the API token. Create one in the dashboard or open a profile session through the API, log in, confirm the application has reached its authenticated page, and save the state. [Browserless profile example]

Save a completed login as a Browserless profile

  1. Create a profile name in the Browserless dashboard, or use the documented API profile flow.
  2. Connect to a live browser session and complete the site’s normal login flow.
  3. Wait for redirects to finish and verify that the signed-in page is visible. Saving before the application sets its final authentication state can produce an unusable profile.
  4. Save the profile using Browserless’s profile save operation. Its browser state can include cookies, localStorage, and IndexedDB. Do not expect sessionStorage to persist.
  5. Use the profile name with subsequent screenshot calls.

Keep the Browserless token and saved profile private. A profile represents an authenticated session, so treat its access like credentials and avoid committing tokens or profile data to source control. Browserless’s docs describe the profile behavior and saving flow. [Authenticated profile docs]

Capture a page with the REST screenshot endpoint

Send the API token and profile in the query string and the target URL in a JSON body. The response is image bytes, so direct the output to a file. This cURL example uses placeholders; replace them locally and do not publish a real token.

curl -X POST \
  "https://production-sfo.browserless.io/screenshot?token=YOUR_API_TOKEN_HERE&profile=my-profile" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://app.example.com/dashboard"}' \
  --output dashboard.png

Browserless documents PNG, JPEG, and WebP response formats and screenshot options. Check the current REST schema when choosing less common options. [REST screenshot API]

Python example

import requests

endpoint = "https://production-sfo.browserless.io/screenshot"
params = {
    "token": "YOUR_API_TOKEN_HERE",
    "profile": "my-profile",
}
response = requests.post(
    endpoint,
    params=params,
    json={"url": "https://app.example.com/dashboard"},
    timeout=90,
)
response.raise_for_status()
with open("dashboard.png", "wb") as image_file:
    image_file.write(response.content)

Node.js example

const endpoint = new URL("https://production-sfo.browserless.io/screenshot");
endpoint.searchParams.set("token", "YOUR_API_TOKEN_HERE");
endpoint.searchParams.set("profile", "my-profile");

const response = await fetch(endpoint, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ url: "https://app.example.com/dashboard" }),
});

if (!response.ok) {
  throw new Error(`Browserless returned ${response.status}: ${await response.text()}`);
}

const image = Buffer.from(await response.arrayBuffer());
await import("node:fs/promises").then(({ writeFile }) =>
  writeFile("dashboard.png", image)
);

These examples save the response as PNG, matching the endpoint’s normal screenshot output. Use the endpoint’s documented request schema for other output formats and capture options.

Adjust the screenshot for the page

Browserless’s screenshot mutation documents these options: [BrowserQL screenshot schema]

Option Use it when Notes
fullPage The whole document should be captured, including below the fold. Long pages can create large images and take longer to render.
type You need PNG, JPEG, or WebP output. Confirm the value and response behavior in the current API schema.
quality You choose JPEG compression. Quality applies to JPEG, not PNG.
selector Only one page element is needed. Use a stable CSS selector and ensure the element exists before capture.
waitForImages Image completion matters to the result. Waiting can increase capture time if resources are slow.
timeout The page needs a different maximum wait. The documented default is 30 seconds; set a higher value only when the page needs it.

Use a selector for a component screenshot rather than capturing a very long full page. For dynamic pages, a fixed delay may be unreliable; prefer a browser session where you can wait for a known selector or perform the required interaction before capturing. Browserless’s screenshot example recommends a browser connection when interaction or waiting is necessary. [Screenshot example]

Other authentication paths

HTTP Basic or proxy challenge

BrowserQL’s authenticate(username, password, origin) mutation supplies credentials to an HTTP authentication challenge. Scope the credentials with an origin where possible; Browserless notes that omitting it applies credentials to every challenge. This is distinct from entering a username and password into an application’s HTML login form. [Authenticate mutation]

If the caller already has valid cookies, BrowserQL’s cookie mutation can set them before navigation. Use the correct domain and path, and preserve the cookie’s security attributes and expiration expectations. A cookie that is valid for one host or path may not authenticate the target URL. [Cookie management]

Interactive or multi-step login

Use a persistent browser session when the flow includes one-time codes, consent dialogs, clicks, or navigation-dependent waits. Browserless sessions preserve state between commands in that session; close the browser when the work is complete. [Create a browser session]

Common problems and fixes

Symptom Likely cause What to check
Screenshot shows the login page The profile was saved before login completed, or the site uses state that is not in the profile. Repeat login, wait for the final redirect and signed-in page, then save again. Check whether the flow depends on sessionStorage, which profiles do not restore.
Screenshot is blank or incomplete The page has not rendered its content, a selector is wrong, or a resource is still loading. Confirm the URL and selector, increase timeout only if needed, and use an interactive session with a page-specific wait for dynamic content.
CAPTCHA or bot-check page appears The site may be blocking automated browsing, or the saved session may no longer be valid. Verify the profile in a live session. Browserless documents an Unblock API that attempts to handle bot detection, but it does not guarantee success against every site. [Unblock API]
HTTP authentication prompt remains An application login flow is being treated as an HTTP challenge, or the challenge credentials are not scoped correctly. Use the authenticate mutation only for HTTP challenges; provide the correct origin. For web-app login, use a profile or interactive session.
Image is cut off or missing Only the viewport was captured, or image loading did not finish. Enable full-page capture when appropriate and use the documented image-wait option when loaded images are required.
Request times out Navigation or resources exceed the configured timeout. Check the target’s load behavior, avoid waiting for unnecessary resources, and raise the timeout within the documented limits if the page genuinely needs more time.
Python or Node saves unreadable output The response was handled as text rather than binary data, or an HTTP error body was saved as an image. Use response.content in Python or arrayBuffer() in Node, and check the HTTP status before writing.

Performance, reliability, and cost considerations

  • Reuse a profile for repeated captures. This avoids replaying a normal login flow on every request, but profiles can stop working when the site expires or rotates its session.
  • Keep waits specific. Waiting for images or a long timeout can improve completeness but adds latency. Capture only the needed element when full-page output is unnecessary.
  • Plan for authentication changes. Sites may require reauthentication, invalidate sessions, or add a flow step. Refresh the saved profile after a confirmed login when captures start returning logged-out content.
  • Protect credentials and session state. Keep tokens out of logs and public repositories, and restrict access to profile names and capture services.
  • Budget from your actual Browserless plan and usage. The cited workflow documentation does not establish a price or benchmark, so check Browserless’s current account and pricing information for applicable costs and limits.

Or skip the browser setup

ScreenshotNeo provides a one-call website screenshot API and an MCP server for AI agents. Its clean-shot flow accepts cookie and consent banners like a visitor, then removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and responses identify the page verdict and billing status in headers. AI agents can use its MCP tools: take_screenshot, get_page_info, and capture_pdf. Read the ScreenshotNeo API docs.

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

Or use Python:

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

Or use Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://app.example.com/dashboard' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo supports PNG, JPEG, WebP, and PDF; full-page and element captures; custom waits, headers, cookies, and authorization; and caching with a chosen TTL. The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is on every plan. This API is a separate capture path and does not reuse a Browserless authenticated profile. [Documentation]

Sign up for 1,000 free screenshots a month, with no card required.

FAQ

Does an authenticated profile include sessionStorage?

No. Browserless documents cookies, localStorage, and IndexedDB restoration, but excludes sessionStorage because it is tied to a tab and may contain short-lived flow state.

Can I use the profile for every website account?

A profile represents the browser state saved under that profile and API token. Create and manage profiles according to the accounts and sessions your workflow needs; do not assume one site’s session authenticates another.

Can Browserless profiles bypass every CAPTCHA?

No guarantee is documented. A CAPTCHA can indicate the site is blocking automation or that the session is invalid; Browserless’s Unblock API is an attempted handling path, not a promise of access.

Can I save the screenshot as a PDF?

This guide uses the screenshot endpoint and image output. For PDF capture, use Browserless’s documented PDF capabilities and verify the endpoint-specific request options. [BAP screenshots and PDFs]