ScreenshotNeo

BlogHow-to

How to Capture Screenshots of a Page Behind a Cloudflare Access Login

Capture an Access-protected page with Cloudflare Browser Run using a service token or session cookie, then verify the rendered screenshot shows the intended content.

By the ScreenshotNeo team4 October 20268 min read

To capture a page behind Cloudflare Access, send the protected URL to a browser-rendering endpoint and include credentials that the Access application authorizes. For recurring automated captures, use a Cloudflare Access service token, configure a matching Service Auth policy, and send the CF-Access-Client-Id and CF-Access-Client-Secret headers. For a one-off capture, a valid CF_Authorization session cookie can work. Cloudflare Browser Run’s screenshot Quick Action accepts custom headers and cookies and returns a rendered screenshot. Use a controlled browser session when the workflow needs interactive steps.

Only capture pages and accounts you are authorized to access. Access credentials grant access; they are not a way to bypass an organization’s policy.

1. Choose the authentication method

Use case Method Tradeoff
Scheduled or unattended capture Service token headers plus an Access Service Auth policy Designed for machine access; requires administrator configuration and secure secret storage.
One-off capture from an authorized user session Valid CF_Authorization cookie Simple, but the session expires and the cookie is sensitive identity material.
Login flow or other interactive browser steps Browser session controlled with Playwright, Puppeteer, or CDP More control than a single stateless screenshot request; requires browser scripting.

For a recurring capture, ask the Access administrator to create a service token and add a Service Auth policy that permits it for the relevant Access application. Cloudflare’s service-token setup describes these credentials for automated systems; the client secret is displayed only once when created. Store it in a secret manager, restrict access, and avoid logging it. See the Cloudflare service-token documentation.

A user session uses the CF_Authorization cookie, which is an identity-bearing JWT. Its lifetime follows the configured session duration; Cloudflare documents a default of 24 hours when neither relevant duration is configured. Do not treat it as a durable automation credential. See Cloudflare’s authorization-cookie documentation.

2. Capture with Cloudflare Browser Run

Cloudflare’s screenshot Quick Action processes the page’s HTML and JavaScript before capturing it. Authenticate the Browser Run API request itself with a Cloudflare API token that has Browser Rendering Edit permission, or use the browser binding from a Cloudflare Worker. Separately, pass the Access service-token headers or session cookie to the target page. These are two distinct credentials: one authorizes use of Browser Run, the other authorizes access to the protected site. Follow the current screenshot endpoint documentation for its endpoint URL and request schema.

Service-token request pattern

The following cURL command illustrates the required target-page headers and screenshot options. Set BROWSER_RUN_SCREENSHOT_URL to the screenshot endpoint URL from Cloudflare’s current documentation, and provide the endpoint’s documented API authentication. The request body fields shown are the Quick Action options; confirm the exact request envelope for the API route you use.

export BROWSER_RUN_SCREENSHOT_URL='<Cloudflare Browser Run screenshot endpoint URL>'
export CLOUDFLARE_API_TOKEN='<Browser Rendering API token>'
export ACCESS_CLIENT_ID='<Access service token client ID>'
export ACCESS_CLIENT_SECRET='<Access service token client secret>'

curl --fail-with-body --silent --show-error \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H 'Content-Type: application/json' \
  --data "{\"url\":\"https://internal.example.com/report\",\"headers\":{\"CF-Access-Client-Id\":\"$ACCESS_CLIENT_ID\",\"CF-Access-Client-Secret\":\"$ACCESS_CLIENT_SECRET\"},\"options\":{\"type\":\"png\",\"fullPage\":true,\"viewport\":{\"width\":1440,\"height\":1000}}}" \
  "$BROWSER_RUN_SCREENSHOT_URL" \
  -o screenshot.png

This command is a request pattern, not a substitute for the current endpoint schema. Cloudflare may distinguish screenshot options from top-level fields depending on the route. Copy the exact documented envelope and authentication setup for your account, while retaining the Access header names and values shown here.

If an authorized user has a valid session cookie, pass it as a cookie header to the target page. Treat the value like a password: do not commit it, print it in logs, or share it in a ticket.

export BROWSER_RUN_SCREENSHOT_URL='<Cloudflare Browser Run screenshot endpoint URL>'
export CLOUDFLARE_API_TOKEN='<Browser Rendering API token>'
export CF_AUTHORIZATION='<valid CF_Authorization cookie value>'

curl --fail-with-body --silent --show-error \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H 'Content-Type: application/json' \
  --data "{\"url\":\"https://internal.example.com/report\",\"cookies\":[{\"name\":\"CF_Authorization\",\"value\":\"$CF_AUTHORIZATION\",\"domain\":\"internal.example.com\",\"path\":\"/\"}],\"options\":{\"type\":\"png\",\"fullPage\":true}}" \
  "$BROWSER_RUN_SCREENSHOT_URL" \
  -o screenshot.png

Use the cookie field format documented for the endpoint in your account. If the Quick Action expects a raw Cookie request header instead, pass CF_Authorization=… in that header. Do not send both methods unless the endpoint documentation requires it.

3. Set the capture scope and wait behavior

Choose the capture options to match the evidence you need. Browser Run’s screenshot Quick Action documents viewport and full-page capture, element selection, image type, and navigation behavior. Consult the endpoint reference for the current field names and supported values.

Need Setting to consider Check
Visible viewport only Set viewport width and height Ensure responsive layout is at the intended breakpoint.
Entire scrollable document Enable fullPage Long or lazy-loaded pages may need extra readiness handling.
One component Use the endpoint’s selector option Confirm the selector matches exactly one intended element.
Late-loading content Set suitable navigation wait options or a page-specific readiness condition where supported Navigation completion may precede application rendering.
JPEG output Set a compatible image type and quality if supported The docs note PNG is the default and quality requires a compatible image type.

Validate the output image. An HTTP-successful response only shows that the screenshot request returned successfully; it does not prove the image contains the protected content rather than an Access login, denial page, or partially rendered app.

4. Use an interactive browser when needed

A single screenshot request is a good fit when the request headers or cookie are enough to authorize the page. Use a browser session if the page requires multi-step navigation, interaction, or state that cannot be represented by a request credential. Cloudflare Browser Run documents browser sessions and getting started with browser control; see Browser Run’s getting-started guide. The same distinction applies if you control another Playwright, Puppeteer, or CDP-based browser: establish authorized access in that browser context, wait for the app to become ready, then capture.

5. Verify access and protect credentials

  1. Open the target URL and confirm it belongs to the Access application covered by the policy.
  2. Check that the service token is active and the Service Auth policy authorizes it for this application.
  3. Confirm the screenshot request includes the Access headers or cookie on the request to the protected site, not only the Browser Run API credential.
  4. Inspect the returned image for the expected page title or content, and check that it is not a login, denial, or error page.
  5. Keep credentials out of source control and request logs. Restrict who can read them, and revoke or rotate credentials under your organization’s policy.

Cloudflare notes that strict service-token authentication can return 401 or 403 on failure instead of redirecting to login. Under strict service-token authentication, successful requests do not establish a reusable CF_Authorization cookie. Check the current behavior and settings in the service-token docs and the Access changelog.

6. Troubleshooting

Symptom Likely cause Fix
401 or 403 from the protected site Invalid or expired service token, missing headers, or a Service Auth policy that does not authorize the token. Verify both Access header names and values, token status, application hostname, and policy scope with the Access administrator.
Screenshot shows an Access login page The request used no valid authorization, the cookie expired, or credentials went to the screenshot service request rather than the target-page request. Use service-token headers with an allowed policy or refresh the authorized session cookie. Confirm the Quick Action forwards credentials to the target page.
Screenshot shows an Access denial page The identity is authenticated but policy does not permit the requested resource, or the token is not allowed by a Service Auth rule. Have the administrator review the Access application and policy. Do not try to work around the denial.
Screenshot is blank or incomplete Page scripts or data were still loading, the URL was wrong, or the selected element did not match. Verify the URL and selector, then use an appropriate wait condition or delay supported by the endpoint and inspect the result again.
API request itself fails authentication The Cloudflare API token is missing or lacks Browser Rendering Edit permission. Configure the Browser Run API credential separately from the Access service token and follow the current API setup guide.
Image type or quality option is rejected Quality was requested for an incompatible format, or the option name/value differs from the endpoint schema. Use PNG defaults or a compatible image type and check the current Quick Action parameter reference.
Cookie-based capture worked once, then stopped The Access session expired or was revoked. Obtain a fresh authorized session or use a service token for unattended automation.

7. Reliability, performance, and cost

Use service tokens for repeatable unattended work because they are intended for automated systems; use session cookies for appropriate short-lived tasks. A cookie expires according to Access session settings, so a scheduled job that depends on a user session needs a renewal plan. A service-token workflow depends on correct policy configuration and secret availability. Neither credential method removes the need to verify the captured page.

Capture only the needed scope: a viewport is generally a smaller artifact than a full-page capture, while full-page and selector choices change the output and may affect how much content must render. Wait for a real page readiness condition when the application loads data after navigation; excessive fixed delays add latency without guaranteeing the content is ready. Cloudflare Browser Run documents Free and Paid plans, but current account quotas and costs are not established here. Check the current Cloudflare plan details before estimating recurring capture costs.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server for developers. For an Access-protected page, it can send custom headers; provide the Access service-token headers through the documented header option and ensure the Access application policy authorizes them. ScreenshotNeo does not bypass Access policy. See the ScreenshotNeo API documentation for the supported request options.

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://internal.example.com/report \
  --data-urlencode 'headers={"CF-Access-Client-Id":"YOUR_CLIENT_ID","CF-Access-Client-Secret":"YOUR_CLIENT_SECRET"}' \
  -o shot.webp

Store the API key and Access secret securely. ScreenshotNeo removes known cookie and consent banners, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server gives AI agents tools for screenshots, page information, and PDF capture. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.

FAQ

Does a successful service-token request create a browser login session?

Not under strict service-token authentication: Cloudflare documents that successful service-token requests do not return a reusable CF_Authorization cookie.

Can I use HTTP Basic Auth for a Cloudflare Access page?

The screenshot Quick Action supports HTTP Basic Auth among its authentication options, but a Basic Auth credential alone does not satisfy an Access policy that requires an Access service token or authorized user session.

Why is the screenshot API token not enough?

The Browser Run API token authorizes the capture service call. The Access credential authorizes the target site. Configure and send both in their correct contexts.

Where can I confirm current Browser Run request fields?

Use Cloudflare’s current screenshot endpoint reference; request schemas and account-level plan details should be checked there before deployment.