Screenshot API FAQ

Find practical answers about getting started, capture settings, quota, errors, automation, and storing your results.

Getting started

What is a Screenshot API?

A Screenshot API loads a URL or raw HTML in a real browser and returns a rendered image or PDF. SnapshotFlow uses Chromium, so JavaScript runs before capture. You can also compare two pages, capture multiple URLs, extract content, or connect an AI agent through MCP.

Read the full answer →
How much does a Screenshot API cost?

SnapshotFlow currently provides 300 free screenshots for the lifetime of your account, with no credit card required. This allowance does not renew monthly. Check your dashboard for the remaining balance. A fresh screenshot uses one unit and a successful visual diff uses two units. The free allowance gives you a way to test your capture workflow before planning larger workloads.

Read the full answer →
Do the 300 free screenshots reset every month?

No. The free allowance is 300 screenshots over the lifetime of your account, rather than 300 each month. The dashboard shows how many you have used and how many remain. A visual diff captures two pages and uses two screenshot units.

Start with 300 free screenshots →
How do I get an API key and try my first screenshot?

Create an account and open API Tokens in the dashboard to copy your token. Send it in the X-Api-Key request header. In the public Playground, you can build and copy requests without an account; add your token to render a live screenshot.

Try the API Playground →
Which programming languages and SDKs can I use?

Any language that can make HTTP requests can use SnapshotFlow, including Python, PHP, Ruby, Go, C#, and JavaScript. Official SDK guides are available for Node.js and Java. The Playground also generates cURL, JavaScript, and Python requests.

Browse code examples →
Can I call the API from browser JavaScript or embed screenshots in my app?

Yes, browser JavaScript can request and display screenshots, but a long-lived API key in public frontend code is visible to visitors. For production, keep the key on your backend and return the image or an appropriate download link to the browser. Download and store files you need to keep rather than relying on a temporary link.

Read the JavaScript guide →

Capture settings

Which image and response formats are supported?

Use format=png, jpeg, webp, or pdf. PNG preserves sharp text and can have a transparent background with omit_background=true. JPEG and WebP support quality from 1 to 100. For the screenshot endpoint, response_type can be image for binary output, base64, json, or url. Choose JSON or base64 when you also need extracted content or metadata.

See the documentation →
Can I render raw HTML without publishing a web page?

Yes. Base64-encode your HTML and pass it in the html parameter. The Playground has an HTML input mode that handles the encoding. Use absolute URLs for external images, stylesheets, and fonts, or embed those assets; relative paths need a usable base URL. Resources must be reachable from the rendering service.

See the documentation →
How do I capture a full-page screenshot?

Set full_page=true to capture the current document height instead of just the viewport. Set width to control the page layout and use a wait condition for dynamic content. This captures the document that has loaded; it does not automatically scroll an infinite feed or guarantee that every lazy-loaded image has appeared.

Read the full answer →
Can a Screenshot API render JavaScript-heavy SPAs correctly?

Yes. SnapshotFlow executes JavaScript in Chromium, including React, Vue, Angular, and Svelte applications. Choose wait_until=load, domcontentloaded, networkidle0, or networkidle2. Add wait_for_selector for an element that appears when your content is ready, and optionally delay in milliseconds, up to 10,000. Network idle alone does not prove that every component has finished rendering.

Read the full answer →
Can I capture mobile and high-resolution screenshots?

Yes. Set width and height, enable viewport_mobile=true for mobile emulation, and use device_scale_factor for pixel density. A value of 2 produces a higher-resolution capture at the same CSS viewport size. The Playground includes device presets. This is Chromium emulation; it does not reproduce every behavior of a physical iPhone or Safari.

See the documentation →
Can I turn a web page or HTML into a PDF?

Yes. Set format=pdf with a URL or base64 HTML input. Use media_type=print for print CSS, pdf_print_background=true for background colors and images, pdf_landscape=true for landscape orientation, and pdf_paper_format for paper size. The default paper format is A4. Wait for your content before exporting.

See the documentation →
Can I capture just one element or crop a screenshot?

Yes. Pass a CSS selector, such as #pricing, to capture a matching element. Use wait_for_selector if it appears after page load. For a rectangular crop, set clip_x, clip_y, clip_width, and clip_height. If the selected element cannot be found, the API returns SELECTOR_NOT_FOUND.

See the documentation →
Can I capture dark mode or reduce animations?

Set dark_mode=true to request the dark color scheme and reduced_motion=true to request reduced motion. The page must honor those browser preferences. For animations that continue, use site-specific CSS through styles, hide changing elements, or add a short delay before capture.

See the documentation →
How do I create thumbnails or reduce the file size?

Use image_width and image_height to resize the captured image while preserving its aspect ratio. These control the output size; width and height control how the website lays out. For smaller files, try JPEG or WebP and lower quality. Test readability, especially for small text, before choosing a very low quality.

See the documentation →
Can I capture a page in another language, timezone, or location?

Use timezone for an IANA timezone and geolocation_latitude and geolocation_longitude for browser geolocation. To request a language, send an Accept-Language value through the JSON headers parameter; the website decides whether to honor it. Browser geolocation and timezone do not change the request IP address or guarantee country-specific content. The current screenshot endpoint does not expose a proxy-country setting.

See the documentation →

Usage and troubleshooting

Are screenshots cached, and how do I force a fresh capture?

The synchronous screenshot endpoint uses a cache for matching capture options. Set cache=false to bypass the lookup and request a fresh render. The X-Cache response header reports HIT or MISS. Content and metadata requests bypass that lookup. Cache duration is configured by the service; it is separate from file storage and download-link expiry.

See the documentation →
Do failed or cached requests count against my screenshot quota?

For a regular synchronous /screenshot request, a cache hit uses no new screenshot unit; a fresh capture is charged after rendering succeeds. A returned image can still use quota if it shows a login screen, CAPTCHA, or incomplete content. Batch and async jobs reserve quota before rendering, so a later render failure can still use a unit. A successful /diff request uses two units because it captures two pages. Check your remaining allowance before retrying large workloads.

See the documentation →
How do I track usage, and what happens when my quota runs out?

The dashboard shows used and remaining screenshot units. Authenticated screenshot responses also expose X-Quota-Used, X-Quota-Limit, and X-Quota-Remaining. If there is not enough quota, a synchronous capture can return HTTP 402 with QUOTA_EXCEEDED. Batch results and async jobs can report the error per item or job. Check your account allowance before submitting more renders.

Check your dashboard →
What does HTTP 429 mean, and how should I retry?

HTTP 429 means you exceeded the request rate limit, which is different from the total screenshot quota. Read retryAfter in the error response and wait before retrying. Reduce parallel requests and use bounded retries with increasing delays. The limit is deployment-dependent; a self-hosted service configures it through MAX_REQUESTS_PER_MINUTE.

See the documentation →
How long does a screenshot take, and what should I do about timeouts?

Capture time depends on the target website, network requests, browser availability, and your wait settings. Cached responses can be faster, but there is no single render time for every page. A navigation timeout can return HTTP 408 with TIMEOUT. Check the target URL, try wait_until=domcontentloaded with a specific readiness selector, and avoid unnecessarily long delays. Async mode avoids holding the client connection open; it does not remove the rendering timeout.

See the documentation →
Why are images, fonts, or page content missing or different?

Common causes include capture timing, lazy loading, inaccessible assets, missing authentication, and blocking rules that remove required resources. Wait for a meaningful selector, add a short delay, and retry with blocking disabled. Serve web fonts instead of relying on operating-system fonts. Full-page capture does not automatically scroll every lazy-loaded section; for a page you control, provide a capture-ready version that loads the required content. Use the same viewport, fonts, and browser preferences when comparing images.

See the documentation →
Can I capture websites protected by a CAPTCHA or bot detection?

Some websites block automated Chromium requests or show a CAPTCHA instead of the intended page. SnapshotFlow does not guarantee access through those protections, and the screenshot endpoint has no CAPTCHA-solving or proxy parameter. For a site you control, provide an authorized capture route or permit the rendering workflow. A successfully rendered challenge page can still count as a screenshot.

See the documentation →

Automation and AI integrations

Can I use a Screenshot API for visual regression testing?

Yes. Call /diff with before and after page URLs, and use response_type=json to read diff_percent, changed_pixels, and total_pixels. Choose response_type=base64 when you want the diff image together with change statistics. Keep the viewport consistent and decide what percentage of changed pixels should fail your CI check. This endpoint renders both URLs; it does not accept a saved baseline image in place of a page URL.

Read the full answer →
What is the best Screenshot API for AI agents?

Choose an API that supports your client, returns useful visual or text evidence, and has clear authentication and usage limits. SnapshotFlow provides a remote MCP endpoint at https://api.snapshotflow.com/mcp, with setup guides for Claude, Cursor, GitHub Copilot, Codex, ChatGPT, and Antigravity. Tools include screenshot, batch_screenshot, visual_diff, extract_text, and check_job. Use the text tool for wording and the screenshot tool for visual layout.

Read the MCP setup guides →
Can I capture multiple URLs in one request?

Yes. Send a JSON POST /batch request with an urls array containing 1 to 10 URLs. Shared options include viewport size, format, quality, and full-page capture. Choose response_type=base64, image_urls, or paths as appropriate for your deployment. Inspect each item in results, because individual captures can fail even when the batch response succeeds. Use separate screenshot calls when each page needs different cookies, selectors, or wait settings.

See the documentation →
Can I run captures asynchronously and receive a webhook?

Yes. Set async=true to receive a job_id and poll /jobs/:id, or provide a publicly reachable webhook_url to receive the result. Production webhook URLs must use HTTPS. Set external_identifier to correlate the callback with your own task. Handle both success and failure, verify signatures when configured, and make your receiver tolerate duplicate deliveries. Job status is temporary, so save completed results promptly.

See the documentation →
Can I get page text, Markdown, or metadata with a screenshot?

Yes. For image captures, set extract_content=true and choose content_format=markdown, text, or html. Add metadata=true for title, description, Open Graph fields, and favicon. Use response_type=json or base64 to receive those fields with the screenshot response. For text without an image, use the /extract endpoint or the MCP extract_text tool.

See the documentation →
Can I schedule screenshots or monitor website changes?

You can call SnapshotFlow from your scheduler, cron job, CI workflow, or automation service. Store the files and timestamps in your own system, and use the diff endpoint to compare two live page URLs. Pin viewport dimensions and define a change-percentage threshold to avoid noisy alerts. SnapshotFlow supplies the capture and comparison API; your workflow controls the schedule, historical archive, and notifications.

Read the monitoring guide →

Storage and deployment

Can I capture authenticated or internal pages?

For a publicly reachable page behind login, pass a JSON cookies array, a JSON headers object with the required Authorization header, or a short-lived URL issued by your application. The hosted service cannot reach your laptop, VPN, or private network. The current URL validator also rejects localhost and private IP addresses, including in the default self-hosted build. A private-network deployment needs an explicitly reviewed access configuration; running Docker alone does not remove that restriction.

Read the full answer →
Can I self-host SnapshotFlow or use my own storage?

Yes. The project includes a Docker deployment path and configurable local, S3-compatible, or Google Cloud Storage backends. Self-hosting means you operate Chromium, storage, capacity, updates, and access controls. Configure storage in the service deployment; a hosted screenshot request does not select an arbitrary customer bucket. Check network-access rules before using it for internal pages.

Read the Docker deployment guide →
Where can I check service status or get help with an error?

Check the status page for service incidents and the API documentation for error codes. When reporting a problem, include the endpoint, response status, error code, capture settings, and time of the request. Remove API keys, session cookies, and private URLs before sharing a reproduction. For a self-hosted deployment, inspect service logs and the /health endpoint as well.

Check service status →

Still have questions?

Try SnapshotFlow free — 300 screenshots for the lifetime of the account, no credit card required. Full docs available instantly.