ScreenshotNeo

BlogHow-to

How to Capture a Full-Page Screenshot of a Long Webpage with Browserless

Capture a long webpage as one image with Browserless. Learn the full-page, lazy-loading, viewport, and readiness settings, plus code and troubleshooting.

By the ScreenshotNeo team4 October 20268 min read

To capture a long webpage as one image with Browserless, send a POST request to its /screenshot endpoint and set options.fullPage to true. Save the binary response directly to a file. If the page loads images or other content only as it scrolls into view, also set scrollPage to true.

This guide uses Browserless’s documented shared SFO endpoint. Use the endpoint that matches your Browserless account’s fleet and region. Keep your API token secret. See the Browserless screenshot API documentation for the current request reference.

Send a full-page screenshot request with cURL

Set your token in an environment variable, then make the request. The response is PNG image data, so use --output to write it to disk rather than trying to parse it as JSON.

export BROWSERLESS_TOKEN='YOUR_API_TOKEN_HERE'

curl --fail-with-body \
  -X POST \
  'https://production-sfo.browserless.io/screenshot?token='"$BROWSERLESS_TOKEN" \
  -H 'Content-Type: application/json' \
  --data '{
    "url": "https://example.com/long-page",
    "scrollPage": true,
    "options": {
      "fullPage": true,
      "type": "png"
    }
  }' \
  --output screenshot.png

scrollPage is useful for triggering lazy-loaded images and other scroll-activated content before capture. It is not a guarantee that every site-specific interaction will load; some pages require clicking a control or running custom browser logic first.

Use Python

This example streams the response to a file and checks for an HTTP error before saving it. Install the dependency with python -m pip install requests.

import os
import requests

TOKEN = os.environ["BROWSERLESS_TOKEN"]
endpoint = "https://production-sfo.browserless.io/screenshot"
payload = {
    "url": "https://example.com/long-page",
    "scrollPage": True,
    "options": {
        "fullPage": True,
        "type": "png",
    },
}

with requests.post(
    endpoint,
    params={"token": TOKEN},
    json=payload,
    stream=True,
    timeout=90,
) as response:
    response.raise_for_status()
    with open("screenshot.png", "wb") as image_file:
        for chunk in response.iter_content(chunk_size=1024 * 64):
            if chunk:
                image_file.write(chunk)

print("Saved screenshot.png")

Use Node.js

With a Node.js version that supports the built-in fetch API, read the response as bytes and write them directly to a file.

import { writeFile } from "node:fs/promises";

const token = process.env.BROWSERLESS_TOKEN;
if (!token) throw new Error("Set BROWSERLESS_TOKEN first");

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

const response = await fetch(endpoint, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    url: "https://example.com/long-page",
    scrollPage: true,
    options: {
      fullPage: true,
      type: "png",
    },
  }),
});

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

const image = Buffer.from(await response.arrayBuffer());
await writeFile("screenshot.png", image);
console.log("Saved screenshot.png");

Understand the full-page settings

Setting What it does When to use it
options.fullPage Captures the full rendered page height instead of only the viewport. The documented default is false. Set it to true for a long, single-image capture.
scrollPage Scrolls the page before capture so content activated by scrolling can load. Use it when the page has lazy-loaded images or scroll-triggered sections.
options.type Selects the image format: PNG, JPEG, or WebP. Choose PNG for a straightforward lossless result. Use a compressed format when file size matters.
options.quality Controls quality for supported compressed formats. Relevant to JPEG or WebP; it does not apply to PNG.
Viewport configuration Sets the browser width and height used to render the page. Choose deliberately when matching a mobile, tablet, or desktop layout. Width affects breakpoints, line wrapping, and total page height.
waitForImages Waits for page images as part of screenshot preparation. Consider it for image-heavy pages where complete image rendering matters.

Browserless also documents navigation and wait options. Pick a readiness condition that matches the page: the fact that navigation completed does not mean every client-rendered section, font, or third-party widget is ready. The BQL screenshot reference lists a 30-second default screenshot timeout; treat that as a default, not a promise that every long or slow page will finish in that time.

Why viewport width matters

A full-page capture covers the document at the browser’s rendered width. A narrow viewport can switch a responsive site to its mobile layout, changing column count, line breaks, sticky elements, and overall page height. Set the viewport intentionally if the image must match a device size or remain comparable across captures.

When scrolling is not enough

Browserless documents scrollPage: true as the approach for triggering lazy-loaded content. A site’s own code may require a particular scroll sequence, a click, consent acceptance, or an application-specific wait. If content is still absent, use an interactive browser session with Puppeteer, Playwright, or Browserless BAP to perform the required actions before taking the screenshot.

Choose the right Browserless route

For one URL-to-image request, /screenshot is the direct route: it accepts an HTTP request and returns image bytes. It does not require you to open and manage a WebSocket browser connection.

  • Use /screenshot for a direct full-page image capture with documented options such as scrolling, image waiting, and output format.
  • Use a connected Puppeteer, Playwright, or BAP browser session when you need to interact with the page, run custom logic, or control steps before capture.
  • Use Smart Scrape when its structured response fits your workflow; its screenshot can be returned as a base64 PNG, and requesting screenshot output forces a browser strategy.
  • Do not assume Agent Run screenshots are full-page. The documented Agent Run screenshot result is a visible-viewport PNG encoded in base64.

A full-page image is also different from a PDF. Browserless’s /pdf endpoint uses Chrome’s print engine and produces selectable text; it does not create a single, full-height PDF page containing the whole webpage. Custom full-page PDF generation is possible through /function. See the Browserless PDF API documentation for the PDF route.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. One GET request takes a URL and returns an image or PDF. For this page, a full-page capture can use the full_page parameter:

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://example.com/long-page \
  -d full_page=true \
  -o shot.webp

See the ScreenshotNeo API documentation for parameters and configuration. ScreenshotNeo accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs.

The free plan includes 1,000 screenshots a month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is on every plan. Sign up for ScreenshotNeo’s free plan.

Troubleshooting

Symptom Likely cause What to try
The image shows only the visible viewport. options.fullPage is missing, misspelled, or false. Set the nested option to the boolean true, then check that you are calling /screenshot.
Images or sections are missing lower on the page. They load only when scrolled into view, or need custom interaction. Set top-level scrollPage: true; consider waitForImages. If the site needs clicks or custom waits, use an interactive browser session.
The page uses the wrong layout or is unexpectedly very tall. The viewport width selected a different responsive breakpoint or text wrapping pattern. Set an intentional viewport width and keep it consistent between captures.
The request returns an HTTP error instead of an image. The token, endpoint, request JSON, or target URL may be invalid; the browser may also fail to load the page. Check the HTTP status and error body, confirm the account’s endpoint and token, and validate the JSON and target URL. Do not save an error response as a PNG.
The file exists but an image viewer cannot open it. An error body or truncated response was written with an image extension. Check the status before writing the body; verify that the response completed and that the chosen type matches the filename.
The capture times out on a long page. Page loading, scrolling, images, or third-party scripts take longer than the configured time allows. Use an appropriate endpoint timeout and readiness condition. Reduce unnecessary waits or use an interactive flow to wait for the specific content needed.
The screenshot is blank or stale. The site may be blocked, still rendering, or serving different content to an automated browser; an intermediary cache may also return an earlier result. Inspect the returned status and response, retry after confirming the page is reachable, and choose a wait condition that matches the content. For changing pages, account for cache behavior if the route supports it.

Performance, reliability, and cost considerations

  • Very long pages produce large images. More page height means more pixels to render, transfer, and store. JPEG or WebP can reduce output size where acceptable; PNG preserves lossless image data but its quality setting is not applicable.
  • Scrolling and readiness waits take time. They can improve completeness for lazy content, while waiting for every resource or network activity can make a capture slower. Wait for the condition that matters to your output.
  • Repeat captures consistently. Fix the viewport, output type, scroll behavior, and readiness settings so layout changes are easier to identify. Dynamic content and third-party resources can still change between requests.
  • Plan for failures. Check status codes before saving bytes, set a client-side timeout suitable for your page, and retry transient failures with a limit and backoff. Avoid unbounded retries that can consume concurrency or account capacity.
  • Protect credentials. Keep the Browserless token in an environment variable or secret store. Avoid placing it in published code, logs, or URLs that may be recorded.
  • Check current pricing separately. Browserless plan pricing and limits can change. Consult its official account and pricing information before estimating production costs; this guide does not assume a particular rate.

FAQ

Does full-page capture include content below the fold?

Yes, options.fullPage: true requests the full rendered page. Content that only loads after scrolling may need scrollPage: true or custom page interaction.

Can I make a full-page screenshot at mobile width?

Yes. Set the browser viewport to the desired mobile width before capture. The page will use whatever responsive layout its own CSS selects at that width.

Does Browserless return JSON for this endpoint?

The direct screenshot endpoint returns image data. Save the response bytes to a file. Some other Browserless workflows can place a screenshot in a structured response, for example as base64.

Is a long screenshot the same as a full-page PDF?

No. A screenshot is a raster image of rendered pixels. The PDF endpoint uses the browser’s print output and does not create one continuous full-height page; custom generation requires a different workflow.

Sources