ScreenshotNeo

BlogHow-to

Three Easy Ways to Screenshot a URL with an API

Capture any public webpage through an HTTP API using three practical approaches, with full-page, selector, wait, format, and troubleshooting guidance.

By the ScreenshotNeo team1 October 20268 min read

The basic pattern is simple: send a URL and capture options to a screenshot service, then save or consume the returned image. The three approaches below cover a direct REST endpoint, an API that returns an image URL or redirect, and a browser automation query interface for cases that need more control.

Choose the right approach

Approach Response Best for Trade-offs
Hosted REST screenshot endpoint Usually image bytes A single request that saves directly to a file Options and session behavior depend on the provider
Hosted API with image URL or redirect JSON containing a CDN URL, a redirect, or image bytes Applications that want a hosted asset URL or batch requests You must handle the provider’s response workflow
Browser automation/query API Often base64 image data Selector capture, clipping, waits, and browser-level control More request structure and provider-specific syntax

Decide first whether you need a viewport screenshot or a full-page image. Then choose the output format, viewport size, readiness condition, and any selector or clip rectangle. Treat API keys as secrets and keep them out of source control.

1. Call a hosted REST screenshot endpoint

A REST screenshot endpoint accepts a URL and options in an authenticated HTTP request and returns image bytes. The following request shape is documented by Browserless:

curl -X POST 'https://production-sfo.browserless.io/screenshot?token=YOUR_API_TOKEN' \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://example.com/","options":{"fullPage":true,"type":"png"}}' \
  --output screenshot.png

Replace YOUR_API_TOKEN with your token and confirm the current endpoint and account requirements in the provider’s documentation. The response is written directly to screenshot.png because this endpoint returns an image response.

Useful REST options

  • fullPage: capture the complete document instead of only the viewport.
  • type: choose an output such as PNG or another format supported by the endpoint.
  • Viewport dimensions: set width and height when responsive layout matters.
  • Selector or clip: capture one element or a rectangle when supported.
  • Wait conditions: wait for a selector, a delay, or a meaningful load state before capture.
  • Lazy content: scroll before capture when images load only after entering the viewport.

Save the response safely

When the endpoint returns binary data, write the response body as bytes. Do not decode it as JSON or text. Check the HTTP status and content type before saving so an HTML error page is not stored with a .png extension.

2. Use an API that returns an image URL or redirect

Some screenshot APIs separate capture from delivery. Screenshot API documents a bearer-authenticated POST request and supports formats including PNG, JPEG, WebP, and PDF, along with viewport dimensions, full-page capture, selectors, waits, custom CSS and JavaScript, and batch requests.

curl -X POST 'https://api.screenshot-api.org/api/v1/screenshot' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://example.com","format":"png","fullPage":true}'

The getting-started workflow describes a JSON result containing a screenshotUrl, or a redirect to image bytes. Inspect the actual response before writing your integration:

# Inspect headers and body first
curl -i -X POST 'https://api.screenshot-api.org/api/v1/screenshot' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://example.com","format":"png"}'

If the response contains a URL, download that URL in a second request. If it is a redirect, follow redirects with your HTTP client. Several advanced options are POST-only, so do not assume that a simplified GET form exposes the same controls.

When this workflow helps

  • Your application wants a URL that can be passed to another service.
  • You need a documented batch endpoint for multiple URLs.
  • You want to request PDF or multiple image formats through one API.

3. Use a browser automation query interface

A browser query interface is useful when a one-action screenshot endpoint is too limited. Browserless documents BrowserQL, where one operation navigates to a page and another returns a screenshot as base64 data.

mutation Screenshot {
  goto(url: "https://example.com") { status }
  screenshot(fullPage: true, type: png) { base64 }
}

Send the mutation through the provider’s authenticated GraphQL or query endpoint, then base64-decode the returned field and write the bytes to a file. The documented controls include full-page capture, clipping, selector capture, output type, quality, image waiting, and timeout.

BrowserQL request flow

  1. Authenticate the request using your Browserless credentials.
  2. Navigate to the target URL.
  3. Wait for the page or a required element if the site renders asynchronously.
  4. Call screenshot with fullPage, selector, clip, type, or quality options.
  5. Decode the returned base64 value and validate the resulting image.

Browserless REST calls are stateless single-action requests. If you need persistent session state or several interactive steps, assess a documented browser mode that supports that state instead of assuming the REST screenshot call will retain it.

Common capture options

Requirement Option to look for Implementation note
Entire page fullPage Long pages can be large and may trigger lazy-loading or memory limits.
One component CSS selector Wait for the selector before capturing; verify it is unique.
Specific rectangle Clip or bounding box Coordinates are usually viewport-relative; confirm the provider’s coordinate model.
Responsive layout Viewport width and height Use the same dimensions in development and production for repeatable output.
Retina output Device scale factor Higher scale improves sharpness but increases bytes and processing work.
Dynamic content Selector wait, delay, or network idle Prefer a meaningful selector over a fixed sleep when possible.
Lazy images Scroll before capture Some pages do not request images until they are near the viewport.
Styling changes Custom CSS or JavaScript Keep injected code deterministic and avoid changing the page before required assets load.
Output PNG, JPEG, WebP, or PDF PNG preserves detail; JPEG and WebP can reduce transfer size; PDF is document-oriented.

Or skip the browser setup

ScreenshotNeo provides a single GET request for PNG, JPEG, WebP, or PDF captures. Its clean-shot pipeline accepts cookie and consent banners like a visitor, then removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture. Each step can be turned off.

Only clean shots are billed. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response identifies the result with X-Page-Verdict and X-Billed headers. ScreenshotNeo also provides an MCP server with take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

See the ScreenshotNeo API documentation for the complete option list.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
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)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' }); const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Features include full-page capture with lazy images loaded, CSS selector capture, dark mode, device presets and custom viewports, retina scale, PDF paper and margin controls, custom CSS and JavaScript, clicks, selector or delay waits, network-idle waits, request blocking, custom headers and cookies, user agents, Authorization, timezone, geolocation, transparent backgrounds, resizing, configurable-TTL caching, signed links, asynchronous jobs with signed webhooks, bulk capture for up to 100 URLs per call, a usage API, and an OpenAPI specification. Common parameter names used by other screenshot APIs also work, which can simplify migration.

There is a free plan with 1,000 screenshots per month and no card. Paid plans start at $5 for 3,000 shots; yearly billing gives two months free, and every feature is available on every plan. Create a free ScreenshotNeo account.

Troubleshooting

The file is blank or incomplete

Cause: the page was captured before client-side rendering finished, or content appears only after scrolling.

Fix: wait for a meaningful selector or network-idle condition, increase the timeout where supported, and scroll before a full-page capture so lazy-loaded sections can render.

The result is a CAPTCHA, 403, or access-denied page

Cause: the target site is detecting automation or requires an interactive challenge. Browserless documents that advanced fingerprinting and interactive challenges can still block REST calls.

Fix: confirm that you are authorized to capture the page, try the provider’s supported browser mode, and treat the challenge page as a failed capture rather than the requested content. No screenshot API can guarantee access to every protected site.

An element screenshot is empty

Cause: the selector does not match, matches a hidden element, or is evaluated before the component mounts.

Fix: verify the selector in a normal browser, wait for it explicitly, and use a clip rectangle only after confirming the element’s position and size.

Your image file contains JSON or HTML

Cause: the endpoint returned an error document or JSON metadata instead of binary image bytes.

Fix: inspect the status, Content-Type, and redirect behavior before writing the body. For URL-based workflows, parse the image URL and make the documented follow-up request.

The full-page image is too large

Cause: a long document, high viewport width, or high device scale factor produces a large bitmap.

Fix: capture a specific element, reduce the scale factor, choose WebP or JPEG where appropriate, or split a long page into sections.

Performance, reliability, and cost

  • Reduce repeated work: cache captures when the page does not change frequently. Use a provider’s TTL option where available.
  • Make readiness deterministic: selector waits are usually more predictable than arbitrary delays, but only if the selector represents the content you need.
  • Control image size: match viewport dimensions and output format to the consuming system. Full-page and retina captures increase transfer and processing cost.
  • Retry carefully: retry transient network or provider errors with bounded exponential backoff. Do not blindly retry CAPTCHA or access-denied responses.
  • Validate outputs: check HTTP status, content type, dimensions, and file size before publishing or storing a capture.
  • Plan for provider differences: compare authentication, output shape, options, batching, session behavior, limits, and target-site reliability for your workload. Pricing and quotas differ and should be checked in current provider documentation.

FAQ

Can an API screenshot a page that requires JavaScript?

Yes, browser-backed services render JavaScript, but you still need an appropriate wait condition and the target may block automation.

Should I use full-page capture for every URL?

No. Use a viewport capture for a visible above-the-fold state and full-page mode when the complete document is required.

Is base64 better than binary image data?

Binary responses are usually simpler and smaller to save directly. Base64 is convenient inside JSON or query workflows but must be decoded before writing an image file.

How do I capture only a card or chart?

Use a CSS selector option when the provider supports it. Otherwise calculate a clip rectangle after the page has rendered and verify the coordinates at the chosen viewport.

Can I capture private pages?

Only when the service supports the required authentication and you are authorized to access the page. Use custom headers or cookies where documented, and keep credentials secret.