Best Website Screenshot APIs for Bulk URL Capture
Compare screenshot APIs for bulk URL capture by execution model, rate limits, delivery, and recovery. Includes runnable code and a practical selection checklist.
Short answer: the right website screenshot API for bulk URL capture depends on how many URLs you need to process, how quickly jobs must start, whether renders run immediately or lazily, and how results are delivered. ScreenshotNeo is the first service to consider when clean screenshots, transparent billing for failed pages, and a low-cost entry plan matter. ScreenshotOne documents bulk URL handling and queue guidance; Urlbox documents batch capture and asynchronous delivery; Browserless documents a direct screenshot endpoint. The available documentation does not establish a like-for-like speed, reliability, or fidelity winner, so run a pilot on your own URLs before committing.
Bulk capture is both an API feature and an operations problem. A batch endpoint can accept many URLs without rendering all of them at once. Your actual completion time and recovery behavior depend on request-start limits, render duration, retry policy, queue durability, and how completed files are collected.
1. What to compare in a bulk screenshot API
| Dimension | What to ask | Why it matters |
|---|---|---|
| Monthly allowance and overage | Are quotas based on successful renders, attempts, or non-cached renders? What happens after the allowance? | A low per-image price can still be expensive if failed attempts count or overages are unclear. |
| Request-start limit | How many API requests may begin in a minute or other time window? | A monthly quota does not tell you how quickly a peak batch can start. |
| Batch semantics | How many URLs fit in a request? Does submitting a batch render now, or create URLs/jobs that render later? | Lazy execution changes when capacity is consumed and when results become available. |
| Delivery | Are results returned synchronously, as URLs, through polling, or by webhook? | Long renders should not require an HTTP connection to stay open for the whole batch. |
| Recovery | Can you retry individual failures? Are jobs durable across process restarts? Can delivery be repeated? | Retries and durable state prevent a single timeout from losing an entire batch. |
| Output and rendering | Which image formats, viewport controls, full-page options, HTML inputs, and output limits are supported? | Small differences in rendering options can make outputs unusable for downstream comparison. |
| Storage and schedule | How long are results retained? Can recurring captures be scheduled or archived? | Retention and scheduling may remove the need to build separate storage and cron workflows. |
| Blocked sites | How are CAPTCHA pages, bot checks, authentication, and site-specific failures exposed? | A successful HTTP response can still contain the wrong page. |
Ask providers about uptime commitments and service terms if those are part of your requirements. The vendor documentation summarized here does not prove comparable service reliability or render fidelity.
2. Screenshot API shortlist for bulk URL capture
This shortlist is ordered with ScreenshotNeo first as the publisher’s product recommendation. It is not a measured performance ranking: the research available does not contain a controlled comparison.
| Service | Documented bulk or delivery model | Good fit to investigate | Check before choosing |
|---|---|---|---|
| ScreenshotNeo | One GET request returns a screenshot or PDF. Also offers bulk capture for up to 100 URLs per call, asynchronous jobs with signed webhooks, and a usage API. | Teams that want clean shots, billing only for clean shots, an MCP server for AI agents, and an entry plan of $5 for 3,000 shots after the free tier. | Validate rendering and throughput on your own representative sites. See the API documentation for request options. |
| ScreenshotOne | Its /bulk endpoint wraps normal screenshot endpoints. Execution is lazy by default: generated render URLs are captured when fetched. Set execute to true to execute during the bulk operation. Bulk and regular requests share a one-minute request bucket. |
Existing integrations or workflows that benefit from generated render URLs and documented queue-based guidance. | Confirm execution timing, current request allowance, and how you will fetch results. The vendor guide’s concurrency fields describe requests that may start in the current minute bucket, not active browser renders. Bulk docs · queue guide. |
| Urlbox | Documents URL and HTML rendering, direct render links, POST requests, and synchronous or asynchronous delivery. Async jobs can be polled or delivered by webhook. Its bulk product page describes batch capture, recurring schedules, archives, and retention. | Workloads that need to investigate scheduled bulk capture and managed result retention. | Verify that the bulk product and API plan include the exact features and volume you need. Docs · API · bulk plans. |
| Browserless | Documents a POST screenshot endpoint accepting a URL and screenshot options, returning image data. | Teams evaluating a direct screenshot endpoint or already using Browserless. | Its documentation notes that blank or altered captures and CAPTCHA pages can indicate the target is blocking automation. Trial the actual destination sites. Screenshot API docs. |
Commercial terms change. ScreenshotOne’s pricing page checked on October 3, 2026 listed up to 100 free screenshots per month and paid tiers showing 2,000, 10,000, and 50,000 monthly screenshots with request-per-minute limits; it says successful renders not served from cache count toward quota. Urlbox’s bulk pricing page checked on the same date showed batches up to 100 and 300 webpages and monthly allowances up to 3,000 and 10,000 captures. Treat these as time-sensitive vendor-published figures and recheck the linked pages before purchase.
3. Estimate capacity before submitting a batch
Separate three quantities that are easy to confuse:
- Monthly successful-render allowance: the amount you can capture in a billing period under the provider’s quota rules.
- Request starts per time window: how many requests can begin within a bucket, such as a minute.
- Active render concurrency: the number of browser jobs rendering simultaneously. A rate-limit counter does not necessarily report this.
Estimate your run from the constraints you can observe. If you have N URLs and can start R jobs per minute, the start-rate lower bound is approximately ceil(N / R) minutes. That is not a completion-time promise: render duration, retries, batch execution semantics, and provider-side scheduling add time. Use measured render durations from a pilot to plan a realistic completion window.
Also account for monthly headroom. If a recurring job captures the same list every day, multiply the URL count by the number of runs, then allow for retries and any additional formats or viewport variants. Clarify whether cached renders, failed renders, and duplicate URLs consume quota under the plan you are considering.
4. Build a reliable bulk capture workflow
- Normalize the input. Validate URL syntax, remove accidental duplicates where appropriate, and assign each URL a stable job ID. Keep query strings intact when they identify different content.
- Choose batch size. Stay within the provider’s documented request or batch limits. Smaller batches reduce the amount of work affected by a single malformed request; larger batches can reduce submission overhead.
- Persist work before submission. Store the URL, job ID, requested options, attempt count, and current state in a durable queue or database for jobs that must survive restarts.
- Respect start limits. Read the provider’s usage or rate-limit information where available. For ScreenshotOne, the guide recommends checking
concurrency.remainingandconcurrency.resetbefore starting more work. These indicate starts allowed in the current minute bucket, not active browser renders. - Use asynchronous delivery for long work. If jobs can outlast a normal request, use polling or webhooks where supported. Persist a job before waiting for its result.
- Make callbacks idempotent. A webhook may be retried, and a worker may restart after saving a file but before marking the job complete. Make processing safe to repeat by keying results on a stable job ID.
- Retry selectively. Retry transient network errors, rate limits, and temporary server errors with exponential backoff and jitter. Do not endlessly retry a permanent invalid URL or a site that consistently blocks automation.
- Validate outputs. Check that the response is an image or expected job payload, that its dimensions and file size are plausible, and that it is not an error page returned with a successful status.
- Record outcomes. Save status, elapsed time, attempt count, output location, and provider billing or page-verdict headers when supplied. This helps separate your own queue delay from render time.
For multiple workers, or retries that must survive restarts, ScreenshotOne’s guide suggests a durable queue such as Redis/BullMQ or SQS. The queue is what makes your work recoverable; the screenshot endpoint alone does not guarantee that your application can resume an interrupted batch.
5. Runnable request examples
These examples use ScreenshotNeo’s one-URL API call to show a complete capture request. For bulk work, submit URLs through the service’s bulk capture capability or orchestrate individual calls with a durable queue and rate control. Keep API keys in environment variables or a secret manager in production. ScreenshotOne supports GET and POST and recommends HTTPS because plain HTTP does not encrypt credentials and other sensitive request data in transit.
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,
)
r.raise_for_status()
content_type = r.headers.get("content-type", "")
if not content_type.startswith("image/"):
raise RuntimeError(f"Expected image response, received {content_type}: {r.text[:300]}")
with open("shot.webp", "wb") as f:
f.write(r.content)
Node.js
const q = new URLSearchParams({
access_key: process.env.SCREENSHOTNEO_API_KEY || 'YOUR_API_KEY',
url: 'https://stripe.com'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status} ${await res.text()}`);
const contentType = res.headers.get('content-type') || '';
if (!contentType.startsWith('image/')) throw new Error(`Expected image, received ${contentType}`);
const data = new Uint8Array(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', data));
For bulk orchestration in Python or Node, read URLs from durable storage, submit only a bounded number concurrently, store each outcome before acknowledging the queue item, and retry only retryable errors. Do not launch an unbounded promise or thread for every URL in a large input file. ScreenshotNeo’s documentation describes its API and available options.
6. ScreenshotNeo capture options relevant to bulk jobs
ScreenshotNeo documents 63 options. Select only what each job needs; every additional variant, such as a second viewport or output format, creates more work and may affect your volume planning.
| Need | Available controls |
|---|---|
| Page extent and target | Full-page capture with lazy images loaded; capture one element by CSS selector; wait for a selector, a delay, or network idle. |
| Appearance | Dark mode; 12 device presets and any viewport; retina scale; transparent background; image resizing. |
| PDF output | Paper size, margins, landscape orientation, and page ranges. |
| Page preparation | Custom CSS and JavaScript; click an element before capture; hide selectors; block ads, trackers, requests, or resource types. |
| Request context | Custom headers, cookies, user agent, and Authorization; timezone and geolocation. |
| Delivery and reuse | Choose a cache TTL; use signed links for public <img> tags; submit async jobs with signed webhooks; bulk capture up to 100 URLs per call; consult the usage API and OpenAPI spec. |
Common edge cases deserve explicit settings: lazy-loaded images may need full-page behavior; single-page apps may need a selector or delay before capture; authenticated pages may require cookies or headers; and a target can return a bot challenge instead of the expected page. Use the smallest wait that reliably exposes the content, then validate output samples.
7. Or skip the browser setup
With ScreenshotNeo, one GET request returns a screenshot, and the API also supports bulk capture for up to 100 URLs per call. See the API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
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 cleanup step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. An MCP server gives AI agents tools for screenshots, page information, and PDF capture. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Every feature is on every plan.
Create a free account and capture 1,000 screenshots a month with no card.
8. Troubleshooting bulk capture
| Symptom | Likely cause | What to do |
|---|---|---|
| Batch submission succeeds but no screenshots appear | The provider creates render URLs lazily, or returns asynchronous job IDs rather than finished images. | Check the response contract. Fetch generated render URLs when required, or poll/receive the async result. For ScreenshotOne bulk, execution is lazy by default unless execute is true. |
| 429 or rate-limit response | Too many requests started in the provider’s time bucket. | Pause until the reset time, reduce workers, and resume with backoff. Do not equate a start limit with browser concurrency. |
| Some jobs disappear after a worker restart | Pending work existed only in process memory, or completion was not committed durably. | Use a persistent queue or database, save state transitions, and make retries idempotent. ScreenshotOne’s guide suggests Redis/BullMQ or SQS for durable multi-worker jobs. |
| HTTP request times out | A synchronous render or batch took longer than the client timeout. | Prefer asynchronous delivery for long jobs, increase client timeout only when appropriate, and retry the individual job rather than blindly resubmitting the whole batch. |
| Blank, altered, or CAPTCHA screenshot | The destination may block browser automation, require a session, or show a challenge to the capture environment. | Test the site directly with the required headers/cookies if supported, and evaluate whether the provider can render that destination. Browserless documents these symptoms as possible blocking indicators; they are not proof of comparative provider reliability. |
| Output is cut off or images are missing | Viewport/full-page settings, lazy loading, or timing did not match the page behavior. | Try full-page capture, wait for a stable selector or content, and compare a sample against the expected viewport and page length. |
| Costs exceed the estimate | Quota may count successful non-cached renders, retries, variants, or multiple daily runs differently than expected. | Review the live plan terms, usage API, cache behavior, retry volume, and number of viewport/format variants. Alert before the quota threshold. |
| Credential or URL data exposed in transit | A request used unencrypted HTTP or credentials were logged. | Use HTTPS, keep secrets out of source control and logs, and redact sensitive query strings. ScreenshotOne explicitly recommends HTTPS. |
9. Performance, reliability, and cost planning
Performance
Measure a representative sample and record submission latency, render duration, output transfer time, and queue delay separately. Include short pages, long pages, authenticated pages, pages with cookie banners, and sites that may block automation. Run at a controlled rate, then increase it within documented limits. This dossier contains no comparable throughput benchmark, so a provider’s advertised batch size should not be treated as a speed guarantee.
Reliability
Define success as a usable screenshot of the intended page, not simply an HTTP 200. Preserve the original URL and a stable job ID; store failure class and attempt history; cap retries; and route persistent failures for inspection. Where webhooks are available, verify signatures and tolerate repeated delivery. Keep a copy of completed outputs in storage you control if provider retention is shorter than your audit or product needs.
Cost
Estimate monthly volume as URLs per run × runs per month × required variants, then add a retry allowance based on your pilot. Compare this with both the monthly quota and request-start limit. Check whether cache hits, unsuccessful attempts, and generated render URLs count. ScreenshotOne’s cited pricing terms count successful renders that are not served from cache; recheck live terms. Urlbox plan limits and prices also change, so verify its live pricing before deciding. ScreenshotNeo’s published tiers are Free for 1,000 shots/month, Starter $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000; annual billing gives two months free.
10. Selection checklist
- List your monthly URL count, peak batch size, run frequency, and number of output variants.
- Confirm request-start limits separately from active-render concurrency.
- Confirm whether bulk submission renders immediately, lazily, or asynchronously.
- Decide how you will fetch results: response body, URL, polling, or webhook.
- Set a durable queue and idempotent retry policy if work must survive restarts.
- Verify output formats, full-page behavior, authentication controls, retention, and scheduling.
- Pilot the same representative URLs against each candidate and compare usable output and failure classes.
- Review live pricing, quota counting, overages, and service commitments before production.
FAQ
Does a bulk endpoint guarantee parallel rendering?
No. Batch submission, request-start allowance, and active browser concurrency are separate behaviors. Check the provider’s execution and delivery documentation.
Should I use one large batch or many small batches?
Use the largest batch that fits the documented limits and your recovery model. Smaller batches isolate malformed input and make partial retries easier; larger ones can reduce submission overhead.
Can I compare providers by monthly screenshot quota alone?
No. Include rate limits, cache and failure billing rules, batch behavior, output retention, and the time required to finish a peak run.
What should I do before capturing thousands of URLs?
Run a representative pilot, validate the images, measure queue and render time, test a restart and retry, then expand volume while watching usage and error categories.
Sources
- ScreenshotOne: Bulk Screenshots, bulk queue guide, options, getting started, and pricing.
- Urlbox: documentation, Screenshot API, bulk capture plans, and API pricing.
- Browserless: Screenshot API.
