Screenshotlayer API Tutorial: Capture a Full-Page Website Screenshot
Use Screenshotlayer’s `fullpage=1` parameter to capture a website’s full height. Learn the request, key options, troubleshooting steps, and a managed alternative.
To capture a website’s full height with Screenshotlayer, send a GET request to http://api.screenshotlayer.com/api/capture with your access_key, a target url that includes its protocol, and fullpage=1. Set viewport separately to control the dimensions used to render the page. This tutorial’s requests are documentation examples; they have not been executed against the API.
1. Make a full-page capture request
Create an API key in your Screenshotlayer account and keep it out of public source code. The API’s documented endpoint is HTTP; the documentation describes HTTPS as a paid feature, so check your plan before changing the scheme.
http://api.screenshotlayer.com/api/capture?access_key=YOUR_ACCESS_KEY&url=https%3A%2F%2Fexample.com&viewport=1440x900&fullpage=1
The target URL must include http:// or https://. URL-encode it when building the query string so its own characters are not mistaken for API parameters.
cURL
curl -G 'http://api.screenshotlayer.com/api/capture' \
--data-urlencode 'access_key=YOUR_ACCESS_KEY' \
--data-urlencode 'url=https://example.com' \
--data-urlencode 'viewport=1440x900' \
--data-urlencode 'fullpage=1' \
--output page.png
Python
import requests
params = {
"access_key": "YOUR_ACCESS_KEY",
"url": "https://example.com",
"viewport": "1440x900",
"fullpage": "1",
}
response = requests.get(
"http://api.screenshotlayer.com/api/capture",
params=params,
timeout=90,
)
response.raise_for_status()
with open("page.png", "wb") as image:
image.write(response.content)
Install the dependency with python -m pip install requests. For production code, check the response content type and API error payload before saving bytes as an image: an unsuccessful response may contain an error description rather than an image.
Node.js
const params = new URLSearchParams({
access_key: 'YOUR_ACCESS_KEY',
url: 'https://example.com',
viewport: '1440x900',
fullpage: '1',
});
const response = await fetch(
`http://api.screenshotlayer.com/api/capture?${params}`
);
if (!response.ok) {
throw new Error(`Screenshotlayer returned HTTP ${response.status}`);
}
const image = Buffer.from(await response.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('page.png', image));
This example uses Node.js with built-in fetch and URLSearchParams. In a service, add a request timeout and inspect the returned content type or documented error fields before treating the body as an image.
2. Understand full-page capture and viewport
fullpage=1 asks for the complete page height. viewport controls the render viewport and is a separate setting: changing the viewport can change responsive layout, line wrapping, and the resulting page height. The specification gives 1440x900 as the default viewport and its product example also uses 2560x1440.
| Need | Setting | What it controls |
|---|---|---|
| Capture the whole page | fullpage=1 |
Requests the target website’s full height. |
| Render at a chosen layout size | viewport=WIDTHxHEIGHT |
The viewport used to render the page, such as 1440x900. |
| Make a compact thumbnail | width |
Requests a thumbnail width; it serves a different purpose from full-height capture. |
For repeatable captures, use the same viewport and target URL. A full-page flag does not guarantee that a page requiring login, delayed client-side rendering, or special interaction will appear in the desired state; the reviewed documentation does not promise behavior for those cases.
3. Choose output and capture options
Keep the initial request small, then add options only when they solve a specific capture requirement.
| Parameter | Use | Notes |
|---|---|---|
format |
Choose an output format. | PNG is the documented default. The FAQ lists JPEG and GIF alternatives. The product page advertises WebP for paid plans; confirm the current plan matrix before relying on it. |
delay |
Wait before capturing. | The FAQ describes this for animations or effects that need time to load. It cannot ensure that every dynamic page has finished rendering. |
ttl |
Set a shorter cache lifetime. | The FAQ gives a default cache duration of 2,592,000 seconds (30 days) and says a custom TTL must be lower. |
force=1 |
Request a fresh capture. | Use when you need to bypass the cached result, rather than reuse it. |
css_url |
Supply CSS for injection. | Useful when you need to adjust page styling for a capture. |
user_agent |
Set the user-agent value. | The rendered site may vary based on user agent. |
accept_lang |
Set the accepted language. | Relevant when the page selects localized content from request headers. |
placeholder |
Configure placeholders. | Check the current API specification for the accepted value and behavior. |
export |
Export to S3 or FTP. | Consult the current specification for the required export settings. |
Format support, HTTPS availability, quotas, and account terms can change. Check the current [Screenshotlayer product page](https://screenshotlayer.com/) and [API specification](https://github.com/apilayer/screenshotlayer-API/blob/master/docs/specifications.md) before building around a plan-specific option.
4. Handle caching, usage, and plan limits
The FAQ says Screenshotlayer caches captures for 30 days by default. A shorter ttl can suit pages that change more often, while force=1 requests a fresh capture. A forced fresh request may use your monthly allowance; check your account’s current usage and billing terms before using it routinely.
The research checked on October 3, 2026 lists the free plan as 100 snapshots per month for non-commercial use, with paid plans beginning at $19.99 per month. The product page and FAQ also describe usage notifications and overage terms, but these are changeable: verify current quotas, commercial rights, overages, and worker concurrency in your account before choosing a plan. The FAQ describes one dedicated worker as handling one screenshot at a time.
5. Troubleshoot common failures
| Symptom or error | Likely cause | What to check |
|---|---|---|
| Missing or invalid access key | The key was omitted, mistyped, or is not valid for the account. | Pass access_key exactly as issued and confirm there are no spaces or placeholder text in the request. |
| Invalid URL | The target is malformed or lacks its protocol. | Use a complete URL such as https://example.com and let a query builder encode it. |
| Invalid API function | The request targets the wrong endpoint or function. | Check the documented endpoint path: /api/capture. |
| Monthly usage allowance reached | The account used its available requests. | Review account usage and plan limits; do not assume an old quota or overage rule still applies. |
| Response saved as a broken image | The client saved an API error body as if it were an image. | Check HTTP status and response type or error fields before writing the response body to an image file. |
| Unexpected page layout | The viewport changes responsive behavior, or the page depends on delayed rendering or authentication. | Set a deliberate viewport, consider the documented delay option, and confirm the page is publicly accessible in the required state. |
| Old page content returned | A cached result was reused. | Review the TTL and use force=1 when a fresh capture is necessary. |
The specification says error responses include an error code, type, and informational message. Log these fields safely, along with the HTTP status, so usage errors can be distinguished from URL or request construction problems. Never log the secret access key.
6. Reliability, performance, and cost considerations
- Keep requests bounded: set a client-side timeout and handle non-success responses. The code examples use a 90-second timeout in Python; choose a limit that fits your application.
- Use caching deliberately: reuse cached output for stable pages; shorten TTL or request a fresh capture when page changes matter. Balance freshness against usage allowance.
- Control concurrency: plan throughput around the worker count on your current plan. The FAQ describes one worker per simultaneous capture; verify present limits before scheduling batches.
- Measure image size: full-height pages can produce large images. Pick a viewport and output format that meet downstream needs, and consider the documented thumbnail-width option if you do not need a full-size image.
- Budget with current terms: account for monthly snapshots, commercial-use permission, output format, HTTPS access, concurrency, and any overage charges. Published prices and limits can change.
7. Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server for developers. Its one-call API can return a screenshot or PDF; see the ScreenshotNeo API documentation.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo removes cookie banners, 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; paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month, with no card.
8. Frequently asked questions
Does fullpage=1 change the viewport?
No. It requests the full page height; viewport separately sets the render dimensions.
What is Screenshotlayer’s default output format?
The specification lists PNG as the default. The FAQ lists JPEG and GIF alternatives, and the product page lists WebP for paid tiers. Verify current availability for your plan.
How long does Screenshotlayer cache a capture by default?
The FAQ states 2,592,000 seconds, or 30 days. Use ttl for a shorter lifetime or force=1 to request a fresh capture.
Can I use the free plan for commercial screenshots?
The reviewed product information describes the free plan as non-commercial. Check the current plan terms before using captures commercially.


