How to Capture a Full-Page Screenshot of a Long HTML Page with Screenshotlayer
Use Screenshotlayer’s `fullpage=1` option to capture a webpage beyond the viewport. Configure the viewport, wait time, format, and cache behavior for long pages.
To capture a long webpage with Screenshotlayer, request the page by its complete URL and set fullpage=1. Choose a viewport width that produces the layout you want, and add a delay if the page needs time to render. The endpoint requires an access key and target URL.
https://api.screenshotlayer.com/api/capture?access_key=YOUR_ACCESS_KEY&url=https%3A%2F%2Fexample.com%2Farticle&viewport=1440x900&fullpage=1&format=png
This requests the full page at a 1440×900 viewport and asks for PNG output. Treat the URL as a request pattern: use your own key and URL-encode parameter values when building the request. Screenshotlayer documents the HTTP endpoint and says HTTPS access is available to paid customers; check your current account terms if HTTPS access matters.
1. Build the request
- Use the Screenshotlayer capture endpoint.
- Pass your account’s
access_keyand a complete targeturlthat includeshttps://orhttp://. - Set
fullpage=1to request the target website’s full height rather than only the selected viewport. - Set
viewportto the dimensions that should control the rendered layout. The reference shows1440x900as the default. - Choose an output
format, and setdelayif the page needs extra time before capture.
The full-page setting asks Screenshotlayer for the page’s full height. The reviewed documentation does not state a maximum page height or guarantee that every scroll-triggered component will load. Check the returned image, especially for unusually long pages.
2. Capture with cURL
cURL can save the returned image directly to a file. The example uses the documented HTTP endpoint and PNG output. Replace the placeholder key and URL with your own values.
curl -G "http://api.screenshotlayer.com/api/capture" \
--data-urlencode "access_key=YOUR_ACCESS_KEY" \
--data-urlencode "url=https://example.com/article" \
--data-urlencode "viewport=1440x900" \
--data-urlencode "fullpage=1" \
--data-urlencode "format=png" \
-o article.png
--data-urlencode handles characters in the target URL and parameter values. Keep the access key out of source control and public client-side code. For repeated captures, put credentials in a secret store or a protected server-side environment variable.
3. Capture with Python
Install the requests package if needed with python -m pip install requests. This example sends the same options, checks for an HTTP error, and writes the response body to a PNG file.
import requests
endpoint = "http://api.screenshotlayer.com/api/capture"
params = {
"access_key": "YOUR_ACCESS_KEY",
"url": "https://example.com/article",
"viewport": "1440x900",
"fullpage": "1",
"format": "png",
}
response = requests.get(endpoint, params=params, timeout=90)
response.raise_for_status()
with open("article.png", "wb") as image_file:
image_file.write(response.content)
Use a timeout appropriate to your application and the target page. If your code needs to distinguish an image from an API error response, inspect the response status and content type before saving the body as an image.
4. Capture with Node.js
This example uses the built-in fetch API available in modern Node.js. It URL-encodes parameters, checks the response status, and saves the image bytes.
import { writeFile } from "node:fs/promises";
const endpoint = "http://api.screenshotlayer.com/api/capture";
const params = new URLSearchParams({
access_key: "YOUR_ACCESS_KEY",
url: "https://example.com/article",
viewport: "1440x900",
fullpage: "1",
format: "png",
});
const response = await fetch(`${endpoint}?${params}`);
if (!response.ok) {
throw new Error(`Screenshot request failed: HTTP ${response.status}`);
}
const image = Buffer.from(await response.arrayBuffer());
await writeFile("article.png", image);
As with Python, check the content type if your caller must reject a non-image response even when the HTTP request itself succeeds. Avoid exposing the key in browser JavaScript or a public application bundle.
5. Tune the capture for long pages
Choose the viewport deliberately
The viewport width can change the responsive layout, which can change the page’s height and content arrangement. A desktop-width capture and a mobile-width capture are different renderings. Set the viewport explicitly when you need repeatable output, and record it with the captured file or job metadata.
Allow time for delayed rendering
Set delay in seconds when scripts, animations, or late-loading content need more time before capture. Screenshotlayer’s product materials recommend a delay for animations and lazy-loaded content. A delay is only extra waiting time: the reviewed reference does not claim that waiting alone triggers every element that loads only after a visitor scrolls. Inspect the result and test the specific page.
Select an output format
The API reference lists PNG as the default. Screenshotlayer’s product materials also list JPG, GIF, and WebP, and describe a quality parameter for lossy formats. PNG is a straightforward choice when you want the documented default; choose a lossy format when its file-size tradeoff suits your use. The reference does not specify format-specific limits for very tall captures.
Refresh cached output when the page changes
The reference lists a default cache TTL of 2,592,000 seconds (30 days). If the page has changed and the returned image appears stale, set force=1 to request a fresh capture. The ttl parameter controls caching; consult your account’s current documentation for the accepted values and behavior before relying on a particular cache policy.
Use stylesheet injection only when you intend to change the page
The optional css_url parameter can attach a stylesheet. That changes the rendered appearance, so omit it when you need a faithful capture of the page as served.
6. Relevant Screenshotlayer options
| Parameter | Purpose | Guidance |
|---|---|---|
access_key |
Authenticates the request | Required. Obtain it from your Screenshotlayer account dashboard and keep it private. |
url |
Selects the page to render | Required. Provide the full URL, including its protocol. |
fullpage |
Requests the target website’s full height | Set to 1 for a full-page capture. |
viewport |
Sets the rendering dimensions and responsive layout | The reference shows 1440x900 as the default. Specify a value to make the intended layout explicit. |
delay |
Waits before capture | Measured in seconds. Use when scripts, animations, or late content need more time. |
format |
Selects the image format | PNG is the documented default; product materials list JPG, GIF, and WebP. |
quality |
Controls lossy image quality | Product materials list it for lossy formats. Check current documentation for accepted values. |
force |
Requests a fresh capture instead of cached output | Set to 1 when you need to bypass an existing cached image. |
ttl |
Configures caching | The reference lists 2,592,000 seconds (30 days) as the default TTL. |
css_url |
Attaches a stylesheet | Use only when changing the page’s appearance is intentional. |
7. Long-page edge cases
- Scroll-triggered content: Some sites load sections only after scrolling. The reviewed documentation does not promise that Screenshotlayer will scroll through the page to activate every such section. Inspect the output and test the target site.
- Responsive reflow: A different viewport width may rearrange columns, navigation, or text, and can affect the full-page height. Use the same viewport when comparing captures.
- Very tall results: Screenshotlayer’s reviewed materials do not state a maximum capture height or output-size limit. Do not assume an unlimited maximum; test the page and ask Screenshotlayer support for an authoritative service limit if your workflow depends on one.
- Freshness: A cached image may show an earlier version of the page. Use
force=1when you need a new render. - Target must be a URL: The reviewed API material describes capturing a website from a URL. It does not establish a way to upload an arbitrary local HTML document as the target.
- Content that needs authentication: The reviewed parameter details do not establish a general authenticated-session workflow. Do not assume a private page can be captured; check the current API documentation for supported access methods.
8. Troubleshooting
| Symptom | Likely cause | What to check |
|---|---|---|
| The image shows only the visible viewport | The full-page option is missing, malformed, or not set to 1. |
Confirm the request includes fullpage=1 and that the parameter is URL-encoded correctly. |
| The request fails before capture | The access key or required URL may be missing or invalid. | Check that access_key and a protocol-qualified url are present, and verify the key in your account. |
| The URL works in a browser but not in the request | Query characters may have been interpreted as API parameters, or the URL may be incomplete. | Pass parameters through a URL encoder such as cURL’s --data-urlencode or Python’s params argument. Include https:// or http://. |
| Lower sections or images are missing | Content may render late or require scrolling to load. | Try an appropriate delay for late rendering, then inspect the result. A delay does not guarantee scroll-triggered content will load. |
| The layout differs from the expected desktop or mobile view | The chosen viewport triggered a different responsive layout. | Set viewport explicitly to the dimensions you want and use the same dimensions for comparisons. |
| The result looks out of date | The service may be returning a cached capture. | Try force=1 to request a fresh capture; the reference lists a 30-day default TTL. |
| The saved file is not a valid image | The response may be an error body rather than image data. | Check the HTTP status and response content type before writing the body as an image. Do not treat every response body as a PNG. |
| An exceptionally long page is incomplete or cannot be captured | The page may exceed an undocumented service limit or encounter target-specific rendering behavior. | Test the target directly and ask Screenshotlayer support about limits before depending on a maximum height. |
9. Performance, reliability, and cost
A full-page result can contain much more image data than a viewport screenshot, and waiting longer adds time to the request. Pick the viewport and format for the job, and use a delay only when the page needs it. The reviewed materials provide no benchmark for capture speed, no maximum output size, and no guarantee for all lazy-loading patterns, so measure your own target pages rather than estimating from page length alone.
For a workflow that can tolerate cached output, the documented default TTL is 30 days. For changed pages, force=1 requests fresh output. Keep credentials private, handle HTTP errors, and validate the returned content before storing it as an image. The research materials do not establish current Screenshotlayer pricing or plan quotas; check the current account terms before estimating costs.
10. Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server for developers. One GET request can return a PNG, JPEG, WebP, or PDF. See the ScreenshotNeo API documentation for request details.
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://example.com/article \
-o shot.webp
ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before the shot. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo’s free 1,000 screenshots a month, with no card required.
FAQ
Does fullpage=1 capture a long page as one image?
It requests the target website’s full height. The reviewed reference does not specify a maximum height, so inspect the returned result for exceptionally long pages.
Will setting a delay load every lazy section?
No guarantee is documented. A delay gives scripts and late content more time, but the reference does not say that it scrolls the page to trigger scroll-based loading.
Can I capture a local HTML file directly?
The reviewed API describes a target website URL. It does not establish support for uploading an arbitrary local HTML document.
Why might two full-page screenshots have different heights?
The viewport can trigger responsive reflow, and dynamic content can change what is rendered. Keep the viewport consistent and check whether the page content changed between captures.


