ScreenshotNeo

BlogComparisons

ScreenshotOne vs ApiFlash: Website Screenshot API Comparison

Compare ScreenshotOne and ApiFlash pricing, capture options, limits, and trade-offs, then choose a screenshot API for your workload.

By the ScreenshotNeo team4 October 202611 min read

Short answer: ApiFlash has the lower published paid entry price: $7 per month for 1,000 screenshots, compared with ScreenshotOne Basic at $17 for 2,000. At 10,000 screenshots per month, ApiFlash Medium is listed at $35 and ScreenshotOne Growth at $79. Those plans have different feature bundles and limits, so the better fit depends on your required options, traffic pattern, and how each service renders your pages. The published information does not establish a reliable winner for speed, uptime, or visual fidelity.

If you want a third option, try ScreenshotNeo first: it removes known cookie and consent banners, newsletter popups, and chat widgets before capture, bills only clean shots, and its paid plans start at $5 for 3,000 screenshots.

1. Comparison at a glance

Question ApiFlash ScreenshotOne
Lowest published paid tier Lite: $7/month, 1,000 screenshots Basic: $17/month, 2,000 screenshots
Published 10,000 screenshot tier Medium: $35/month Growth: $79/month
Largest listed tier in this comparison Large: $180/month, 100,000 screenshots Scale: $259/month, 50,000 screenshots
Free allowance 100 screenshots/month 100 screenshots/month
Common formats and capture modes PNG, JPEG, WebP; full-page and mobile capture PNG, JPEG, WebP; full-page and mobile capture
Published request-rate terms 20 requests/second sustained, burst bucket of 400 40, 80, and 150 requests/minute on Basic, Growth, and Scale

These are vendor-published figures collected on October 3, 2026, and can change. Confirm current prices, quotas, feature availability, and overage rules before purchasing. ScreenshotOne pricing; ApiFlash plan page.

2. How to interpret the price difference

For a small workload, ApiFlash Lite is the lower-cost paid entry. It includes half the monthly allowance of ScreenshotOne Basic. At the 10,000-per-month tier, ApiFlash Medium is listed at less than half the price of ScreenshotOne Growth, while the allowances match. The higher ApiFlash Large tier lists twice the quota of ScreenshotOne Scale for a lower monthly price.

These are not feature-equivalent plans. ScreenshotOne lists PDF rendering, HTML rendering, caching, S3 delivery, webhooks, signed links, and integrations; some higher-tier features include choosing IP location, scrolling screenshots, video, and GPU rendering. ApiFlash documents controls for viewport, element capture, CSS/JavaScript injection, cookies and headers, wait behavior, location, extracted HTML/text, and S3-compatible delivery. Verify that the specific plan you are considering includes the options you need. ScreenshotOne plan features; ApiFlash API documentation.

Do not compare the raw per-image division as a guaranteed effective cost. Your actual spend depends on successful unique captures, cache behavior, overages, retries, and whether visual defects still count. ScreenshotOne says successful uncached unique renders count; ApiFlash says cached and failed screenshots do not count. Check each provider’s current terms for your exact workload.

3. Request limits, reliability, and visual quality

The limits use different units. ScreenshotOne lists a per-minute request allowance by plan. ApiFlash documents a leaky bucket with a sustained rate of 20 requests per second and a burst capacity of 400; traffic above the sustained rate is delayed, and excess beyond the burst can receive HTTP 429. A system that sends short bursts should model the bucket and response behavior rather than compare only monthly quotas. ScreenshotOne limits; ApiFlash rate limits.

Neither vendor feature descriptions nor ApiFlash’s description of its Chrome and AWS Lambda infrastructure prove which API is faster or more reliable for your targets. ApiFlash says it does not publicly display uptime statistics. No controlled head-to-head speed, uptime, or visual-fidelity evidence is available in the reviewed material. If those qualities affect your product, run a repeatable trial using your own pages and record both successful responses and visual outcomes. ApiFlash FAQ.

4. Which service fits your use case?

  • Choose ApiFlash for evaluation when the lower listed entry price matters, your volume fits its plan, and its documented capture parameters cover your requirements.
  • Choose ScreenshotOne for evaluation when the 2,000-shot Basic allowance or its documented workflow features such as PDFs, webhooks, signed links, S3 delivery, or higher-plan video fit your system.
  • Try ScreenshotNeo first when clean output matters: consent banners, newsletter popups, and chat widgets are removed before capture; bot checks, blank pages, timeouts, failed loads, and cache hits are not billed. It also offers an MCP server for AI agents and a $5 paid tier for 3,000 shots.

For any provider, start with your monthly successful unique captures, required formats and page modes, content readiness needs, and the largest burst your application can generate. Then compare the plan’s rate, quotas, feature access, billing behavior, and support requirements against that workload.

5. Try the APIs with the same request

The examples below request a WebP capture of the same page and save the response body. Keep API keys on a server or in a secret manager; do not publish them in browser-side JavaScript. Use a URL-encoding library because target URLs and option values can contain reserved characters. ApiFlash defaults to JPEG unless you set format; ScreenshotOne requires its own access key and documents its endpoint and parameters in its API documentation.

cURL

# ApiFlash
curl -G 'https://api.apiflash.com/v1/urltoimage' \
  --data-urlencode 'access_key=YOUR_APIFLASH_ACCESS_KEY' \
  --data-urlencode 'url=https://example.com' \
  --data-urlencode 'format=webp' \
  --data-urlencode 'full_page=true' \
  -o apiflash.webp

# ScreenshotOne
curl -G 'https://api.screenshotone.com/take' \
  --data-urlencode 'access_key=YOUR_SCREENSHOTONE_ACCESS_KEY' \
  --data-urlencode 'url=https://example.com' \
  --data-urlencode 'format=webp' \
  --data-urlencode 'full_page=true' \
  -o screenshotone.webp

Python

import os
import requests

TARGET = "https://example.com"

cases = [
    (
        "ApiFlash",
        "https://api.apiflash.com/v1/urltoimage",
        os.environ["APIFLASH_ACCESS_KEY"],
        "apiflash.webp",
    ),
    (
        "ScreenshotOne",
        "https://api.screenshotone.com/take",
        os.environ["SCREENSHOTONE_ACCESS_KEY"],
        "screenshotone.webp",
    ),
]

for name, endpoint, key, filename in cases:
    response = requests.get(
        endpoint,
        params={
            "access_key": key,
            "url": TARGET,
            "format": "webp",
            "full_page": "true",
        },
        timeout=90,
    )
    response.raise_for_status()
    content_type = response.headers.get("content-type", "")
    if not content_type.startswith("image/"):
        raise RuntimeError(f"{name} returned {content_type}: {response.text[:500]}")
    with open(filename, "wb") as output:
        output.write(response.content)
    print(f"Saved {filename} ({len(response.content)} bytes)")

Node.js

import { writeFile } from "node:fs/promises";

const target = "https://example.com";
const providers = [
  {
    name: "ApiFlash",
    endpoint: "https://api.apiflash.com/v1/urltoimage",
    key: process.env.APIFLASH_ACCESS_KEY,
    file: "apiflash.webp",
  },
  {
    name: "ScreenshotOne",
    endpoint: "https://api.screenshotone.com/take",
    key: process.env.SCREENSHOTONE_ACCESS_KEY,
    file: "screenshotone.webp",
  },
];

for (const provider of providers) {
  if (!provider.key) throw new Error(`Missing API key for ${provider.name}`);
  const query = new URLSearchParams({
    access_key: provider.key,
    url: target,
    format: "webp",
    full_page: "true",
  });
  const response = await fetch(`${provider.endpoint}?${query}`, {
    signal: AbortSignal.timeout(90_000),
  });
  if (!response.ok) {
    throw new Error(`${provider.name} returned HTTP ${response.status}: ${await response.text()}`);
  }
  const type = response.headers.get("content-type") ?? "";
  if (!type.startsWith("image/")) throw new Error(`${provider.name} returned ${type}`);
  await writeFile(provider.file, Buffer.from(await response.arrayBuffer()));
  console.log(`Saved ${provider.file}`);
}

These examples use matching basic options, not every available parameter. Confirm exact parameter support and plan access in the provider documentation before porting an existing integration. Do not assume similarly named settings produce identical browser behavior.

6. Compare fairly with a small evaluation

  1. Choose representative URLs: a simple static page, a page with client-rendered content, a long or lazy-loaded page, and an authenticated page if that is part of your use case.
  2. Use the same viewport, format, target state, and wait condition wherever both APIs offer comparable controls.
  3. Run repeated captures at realistic intervals. Record HTTP status, content type, image dimensions, file size, elapsed time, and whether expected content appears.
  4. Test cache hits separately from fresh captures. Account for the providers’ different cache and billing rules.
  5. Test concurrency and bursts within the plan’s documented request limits. Observe throttling and retry behavior instead of retrying aggressively.
  6. Price the observed workload, including failed attempts, cache misses, needed upgrades, and any enabled overage.

This is an evaluation method, not a claim that either service has a particular latency or success rate. Keep the page set and request options stable if you repeat the comparison after a plan or integration change.

7. Options that matter for real captures

Need ApiFlash documentation Comparison note
Image output format: PNG, JPEG, WebP; JPEG/WebP quality can be set ApiFlash documents JPEG as the default. Set a format explicitly to make comparisons reproducible.
Viewport and mobile width, height, scale_factor, and user_agent Set viewport and device scale to the dimensions your product needs.
Full page or element full_page, element, element_overlap, crop ApiFlash documents element capture as the first CSS-selector match; element is ignored when full-page mode is true.
Timing and lazy content wait_until, wait_until_timeout, wait_for, delay, scroll_page Prefer a relevant selector or readiness condition to an arbitrary delay where possible. A full-page image and a prior scroll can have different effects on lazy content.
Page modifications css, js, headers, cookies, accept_language URL-encode special characters. Treat cookies and authorization headers as secrets.
Location and background latitude, longitude, accuracy, time_zone, transparent ApiFlash documents transparency for PNG when the page body background is transparent.
Cache and delivery fresh, ttl, response_type, S3 parameters ApiFlash documents a default cache TTL of 86,400 seconds and a maximum of 30 days. JSON mode returns links and can include extracted HTML/text.

For ScreenshotOne, consult its options documentation for current parameter names, accepted values, plan restrictions, and response formats. When migrating, map behavior field by field and validate the resulting image: matching option names do not guarantee matching rendering semantics.

8. Cost, performance, and reliability planning

Estimate monthly spend

Start with unique captures that need a fresh render, not total page views. Estimate how many requests can use cache, how often page state changes, how many retries are expected, and whether failed attempts are billable under the current terms. Compare that estimate with each plan’s allowance and overage policy. Avoid relying on a single nominal price-per-screenshot calculation when your application needs large bursts or features gated to a higher tier.

Manage latency and throughput

  • Cache outputs when the source content and requested options have not changed.
  • Use a queue for batch work and limit concurrency to the provider’s current allowance.
  • Use readiness conditions for dynamic pages; do not add a long fixed delay to every request without measuring its effect.
  • Choose an output size and format appropriate to the consumer. Higher resolution and full-page captures can produce larger files.
  • Set an application timeout that allows for page rendering while preventing requests from hanging indefinitely.

Make failures recoverable

Separate invalid requests and authentication errors from temporary network or provider failures. Retry only transient failures, use bounded exponential backoff with jitter, and honor rate-limit responses. Avoid parallel retries that create a larger burst. For workflows where a screenshot must be retained, persist the image in storage your application controls rather than depending on a temporary response URL.

9. Troubleshooting common problems

Symptom Likely cause What to do
HTTP 400 from ApiFlash Invalid parameter, malformed URL, or target that cannot be captured Include https:// or http://, URL-encode values, and inspect the response message. Try the target URL in a browser.
HTTP 401 Missing, invalid, or revoked access key Check the secret configured on the server and confirm the correct provider key is being sent.
HTTP 402 from ApiFlash Monthly quota exceeded Check current quota, reduce unnecessary fresh captures, or select a plan with enough allowance.
HTTP 403 from ApiFlash A requested option is not available on the current plan Check the plan’s feature access or remove the restricted option.
HTTP 429 Rate limit or burst limit reached Reduce concurrency, queue work, and retry after a delay with backoff. Do not immediately replay the entire batch.
Blank or incomplete screenshot Capture happened before app content appeared, lazy content was not loaded, or the target failed Wait for a meaningful selector or supported readiness condition, consider scrolling where appropriate, and inspect the target’s own response.
Cookie wall or popup obscures content Consent handling is disabled, unsupported, or behaves differently on the page Check the provider’s cleanup option and test the actual target. ScreenshotNeo removes 60+ known consent platforms, newsletter popups, and chat widgets before capture.
Fonts or styles differ External font/resource failures, custom headers, or environment differences Check resource loading and whether headers affect cross-origin assets. ApiFlash notes that custom headers apply to requests including font requests; test with and without them.
Saved file contains JSON or an error page The API returned an error body or JSON response, not image bytes Check HTTP status and Content-Type before writing the response as an image. Keep an error-body excerpt in logs, but redact secrets.
Repeated calls return stale content A cached image was returned Adjust TTL or use ApiFlash fresh=true for a fresh capture, and account for the resulting extra render.

ApiFlash documents HTTP 400, 401, 402, 403, 429, and 500 response meanings in its API documentation. Error handling and plan behavior can change, so refer to the current docs when diagnosing a production incident.

10. Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. A GET request with a URL returns PNG, JPEG, WebP, or PDF. The same call can be used from a backend without managing browser infrastructure. 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,
)
r.raise_for_status()
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}`);
if (!res.ok) throw new Error(`ScreenshotNeo returned HTTP ${res.status}`);
const bytes = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', bytes));
  • Cookie banners, popups, and chat widgets are removed before the shot; each cleanup step can be turned off.
  • Bot checks, blank pages, timeouts, failed loads, and cache hits are never billed; responses identify page verdict and billing status in headers.
  • An MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs.
  • 1,000 screenshots per month are free with no card; paid plans start at $5 for 3,000 screenshots.

Sign up for ScreenshotNeo’s free 1,000 screenshots per month—no card required.

11. FAQ

Which API is cheaper for 1,000 screenshots?

ApiFlash Lite is listed at $7/month for 1,000 screenshots. ScreenshotOne Basic is listed at $17/month for 2,000. Both list a free 100-screenshot monthly allowance; confirm current terms before choosing.

Do both APIs support full-page screenshots?

Yes, both publish full-page capture support. ApiFlash documents full_page=true. Test very long and lazy-loaded pages with your actual targets.

Is either service proven faster?

The reviewed sources do not provide a controlled independent speed comparison. Run the same representative pages and options against both if latency is a selection criterion.

Can I use the same options when switching providers?

Use the providers’ documentation to map each setting, then compare output. Similar labels may have different defaults or rendering behavior.

Are the listed prices permanent?

No. They are a dated vendor-page snapshot researched October 3, 2026. Check the provider pricing pages for current amounts, quotas, and restrictions.