ScreenshotNeo

BlogHow-to

Can Screenshot APIs Capture Pages Behind a Login?

Yes, if the capture browser receives valid authentication state. Learn how to pass headers or cookies, reuse browser state, and troubleshoot protected-page captures.

By the ScreenshotNeo team4 October 20267 min read

Yes. A screenshot API can capture a page behind a login when its rendering browser receives authentication state the target website accepts. Depending on the site, that may mean an authorization header, current session cookies, or saved browser state from a completed login. Sending only the protected URL does not sign you in.

The right setup depends on how the site authenticates users. Before implementing it, confirm you are authorized to access the account and automate the capture, then identify whether the site uses HTTP credentials, cookies, or browser state such as local storage.

1. Identify the login mechanism

Check the application’s authentication flow or ask its owner. Common patterns include:

  • HTTP Basic authentication: The server challenges the request and accepts credentials in an Authorization header.
  • Bearer or API token: The application accepts an Authorization header or another documented token header.
  • Cookie session: A browser receives a session cookie after login and sends it on later requests.
  • Browser-managed state: The application also depends on local storage, IndexedDB, or a completed interactive login flow.

There is no universal “login” parameter for screenshot APIs. Their supported header, cookie, and browser-state formats differ, so check the provider’s current API reference.

2. Pass an authorization header

Use a header when the target accepts HTTP authentication directly. For example, a service may let you provide an Authorization header containing a bearer token. The following pattern uses placeholder values; replace the option syntax with the screenshot provider’s documented format.

curl -G "SCREENSHOT_API_ENDPOINT" \
  --data-urlencode "url=https://example.com/account" \
  --data-urlencode "authorization=Bearer YOUR_TOKEN" \
  -o account.png

Some providers take authorization separately; others accept a custom-header option. For HTTP Basic authentication, follow the provider’s documented encoding and field names. Do not put a real token in a public URL, shared shell history, or client-side code.

3. Pass current session cookies

If login creates a cookie session, obtain the current cookies through an authorized sign-in flow and pass them in the format your provider supports. Preserve the cookie’s applicable domain and path when the API supports those attributes. A cookie scoped to a different host or path may not be sent to the protected page.

curl -G "SCREENSHOT_API_ENDPOINT" \
  --data-urlencode "url=https://example.com/account" \
  --data-urlencode "cookies=SESSION_COOKIE=YOUR_CURRENT_VALUE" \
  -o account.png

This is a format illustration, not a real cookie or a universal provider parameter. Some APIs accept structured cookie objects with fields for name, value, domain, path, and expiry; use their exact schema. Never copy real session-cookie values into published examples.

Cookies expire, rotate, and can be invalidated when a user signs out or changes security settings. Refresh them through the authorized login process when that happens. Do not assume a cookie captured once will remain valid indefinitely.

4. Reuse authenticated browser state

A saved browser profile or storage-state file is useful when a full browser login is needed. Sign in in a controlled browser session, save the supported state, then load it into the browser context used for capture. Browserless documents saving and reusing a logged-in profile; Playwright documents saving and restoring authenticated storage state.

import { chromium } from 'playwright';

const browser = await chromium.launch();
const context = await browser.newContext({
  storageState: 'playwright/.auth/state.json'
});
const page = await context.newPage();
await page.goto('https://example.com/account');
await page.getByRole('heading', { name: 'Account overview' }).waitFor();
await page.screenshot({ path: 'account.png', fullPage: true });
await browser.close();

To create the state file, complete login in an authorized browser session and save the context state using Playwright’s documented authentication workflow. Treat the file as a secret: it can contain cookies and headers that could let someone impersonate the account. Keep it out of source control and restrict access. Playwright’s guide specifically warns that saved browser state may contain sensitive authentication material.

Storage-state support does not necessarily cover every browser storage mechanism. Playwright supports local storage and can include IndexedDB when configured; session storage is not normally persisted by its storage-state API and needs separate handling. Verify which mechanism the target application relies on.

5. Wait for the authenticated page

A successful navigation does not guarantee the signed-in content is ready. The site may redirect through login, render the application after navigation, or show an error inside the page. Wait for a page-specific signal such as an account heading, signed-in navigation item, or expected URL before taking the screenshot.

await page.goto('https://example.com/account');
await page.waitForURL('**/account');
await page.getByRole('heading', { name: 'Account overview' }).waitFor();
await page.screenshot({ path: 'account.png', fullPage: true });

Choose a marker that appears only in the authenticated view. A generic page-load event can fire before application data or protected content has rendered.

6. If you administer the website

If you own or administer the target site, you can configure its network or authentication layer to permit the screenshot service. For example, a narrowly scoped firewall allowlist may be appropriate. Keep the access rule limited to the authorized service and required routes, and maintain it as the service’s network details change. Do not weaken access controls on a site you do not control.

Method comparison

Method Best fit Ongoing work Main caution
Authorization header The site accepts Basic credentials or a token directly Refresh or rotate credentials when required Keep credentials secret and scoped
Cookies The site uses a browser session cookie Refresh expired or rotated cookies Match domain and path; protect session values
Saved browser state Login needs a browser flow or browser storage Recreate state when login expires or changes Saved state may enable account impersonation
Owner-configured access You administer the target site Maintain the access rule Keep the allowlist narrow

Security checklist

  • Use HTTPS for requests that carry API keys, authorization values, or cookies.
  • Use a dedicated account with the minimum access needed for the capture.
  • Store credentials and browser-state files in a secret manager or another access-controlled location.
  • Keep secrets out of public source code, screenshots, logs, and shared command history.
  • Rotate or revoke credentials when they are no longer needed.
  • Confirm the target site permits the requested automated access.

Troubleshooting

What you see Likely cause What to check
A login form instead of the page No usable session reached the page, the token is invalid, the cookie scope is wrong, or the state expired Confirm the credential works through the authorized browser flow; check cookie domain and path; refresh expired state
A redirect back to sign-in The app rejected the supplied authentication or requires another login step Inspect the redirect destination and the site’s documented authentication requirements
A CAPTCHA, bot check, or blank capture The site may block automation or require an interactive challenge Check the provider’s response and site policy; ask the site owner about an authorized access path
Only part of the page is visible Capture began before the authenticated app finished rendering Wait for a signed-in page marker or application-ready signal
Cookies are present but do not authenticate Cookie domain/path mismatch, expiry, rotation, or a missing companion cookie Re-export current cookies from the authorized session and preserve supported scope attributes
Cookie-only setup still shows signed out The app may rely on local storage, IndexedDB, or session storage as well Use supported browser storage state or handle the required storage mechanism explicitly
It works once, then fails later The site expired or revoked the session, or its login flow changed Refresh state and review the login flow; do not treat saved state as permanent

Performance, reliability, and cost

Authenticated captures add setup and maintenance: login state must be created, protected, and refreshed. Browser-profile reuse can avoid repeating an interactive login for every capture, but it does not prevent session expiry. Waiting for a precise authenticated-page marker improves reliability by avoiding premature captures; avoid arbitrary long delays when a specific signal is available.

Capture cost and behavior depend on the provider’s pricing and failure policy. Check whether failed loads, blocked pages, retries, or cached results are billable before putting a flow into production. For recurring jobs, record whether each result is a signed-in page, a login redirect, or a blocked response so failures are detectable rather than silently accepted.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. Its API accepts custom headers and cookies, along with options including selector waits, delays, and network-idle waits. See the ScreenshotNeo API docs for request parameters. For an authorized page where the site accepts a bearer token, a request looks like this:

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://example.com/account \
  -d authorization="Bearer YOUR_TOKEN" \
  -o account.webp

Or use Python:

import requests

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

Or Node.js:

const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://example.com/account',
  authorization: 'Bearer YOUR_TOKEN'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('account.webp', Buffer.from(await res.arrayBuffer())));

Use only authentication material the target site authorizes, and confirm the API option format in the docs. Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. An 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 free.

FAQ

Can a screenshot API log in for me?

Some browser automation systems can perform a login flow, but the setup depends on the target site and the provider. This guide covers passing valid state or reusing state created through an authorized login.

Will a screenshot API work on every private dashboard?

No. The site must accept the supplied state, and automation blocks or site-specific behavior can prevent a capture.

Only if you are authorized to use it for the capture and can store and transmit it securely. A dedicated, limited account is safer for recurring automation.

Does a saved browser profile stay logged in forever?

No. Sessions can expire, rotate, or be revoked, and login requirements can change. Plan how to refresh the state.