Cloudinary vs Browserless for Screenshot API Workflows
Compare Browserless’s browser capture API with Cloudinary’s URL2PNG add-on, then choose a workflow for capture, asset transformation, or both.
Short answer: For an API whose main job is to open a webpage and return a screenshot, Browserless is the more direct documented fit: its REST /screenshot endpoint accepts a URL and capture options, then returns image data. Cloudinary is primarily a media management, transformation, optimization, and delivery platform; it can also generate website screenshots through its url2png delivery type, which requires the URL2PNG Website Screenshots add-on. Confirm that add-on is available to your account and review its current billing before building around it.
If you want a screenshot API to handle browser rendering and cleanup in one call, try ScreenshotNeo first: it removes common consent banners, popups, and chat widgets before capture, and bills only clean shots.
What each service does
Browserless: browser capture
Browserless documents an HTTP task API at /screenshot. You send a page URL or inline HTML with screenshot and navigation options; the response is the image bytes. The current REST API documentation describes viewport and full-page capture, element selection, image format, clipping, waiting, and request controls. If you need to interact with a page or run more involved browser automation, Browserless also documents WebSocket connections using Puppeteer or Playwright.
Cloudinary: media lifecycle, with a screenshot add-on
Cloudinary’s core workflow is to upload and manage media, transform it through URLs or SDKs, optimize it, and deliver it through its CDN. Its delivery-type documentation also lists url2png for website screenshot generation and says it requires the URL2PNG Website Screenshots add-on. Treat that as an add-on-dependent capability, not as a standard browser automation endpoint. Verify current availability and cost with Cloudinary before depending on it.
These services are not necessarily alternatives in every architecture. A browser capture service can produce the image, and a media platform can then store, transform, optimize, or deliver that image if those steps fit your system.
Choose by workflow
| Your requirement | Documented fit | Why |
|---|---|---|
| Navigate to a webpage and return image bytes over one HTTP request | Browserless | The REST screenshot endpoint accepts a URL and capture configuration. |
| Capture a viewport, full page, or selected element | Browserless | The screenshot API documents these capture controls. |
| Interact with the page or reuse browser automation code | Browserless | Its WebSocket connection path supports Puppeteer and Playwright workflows. |
| Transform, optimize, manage, and deliver captured assets | Cloudinary | These are central parts of its media API and transformation workflow. |
| Generate a website screenshot in a Cloudinary workflow | Cloudinary URL2PNG add-on | The delivery types documentation lists url2png; the add-on is required. |
| Capture with consent cleanup and clear per-response billing outcomes | ScreenshotNeo | It removes supported consent platforms, newsletter popups, and chat widgets; failed or non-clean outcomes and cache hits are not billed. |
This is a comparison of documented functional fit, not a speed, fidelity, or reliability benchmark. The research sources do not establish comparable current pricing, quotas, or the Cloudinary screenshot add-on cost. Compare current plan terms against your expected capture volume and image processing needs.
Browserless REST screenshot: runnable examples
The current Browserless REST API uses a POST request to /screenshot, with the token as a query parameter, a JSON body, and image data in the response. Replace the placeholder token and choose a page you are authorized to access. The examples save the response body as a PNG file.
cURL
curl -X POST 'https://production-sfo.browserless.io/screenshot?token=YOUR_BROWSERLESS_TOKEN' \
-H 'Content-Type: application/json' \
--data '{"url":"https://example.com","options":{"fullPage":true,"type":"png"}}' \
--output screenshot.png
Python
import requests
endpoint = "https://production-sfo.browserless.io/screenshot"
response = requests.post(
endpoint,
params={"token": "YOUR_BROWSERLESS_TOKEN"},
json={
"url": "https://example.com",
"options": {"fullPage": True, "type": "png"},
},
timeout=90,
)
response.raise_for_status()
with open("screenshot.png", "wb") as image_file:
image_file.write(response.content)
Node.js
const endpoint = new URL("https://production-sfo.browserless.io/screenshot");
endpoint.searchParams.set("token", "YOUR_BROWSERLESS_TOKEN");
const response = await fetch(endpoint, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
url: "https://example.com",
options: { fullPage: true, type: "png" },
}),
});
if (!response.ok) {
throw new Error(`Screenshot request failed: ${response.status} ${await response.text()}`);
}
const image = Buffer.from(await response.arrayBuffer());
await import("node:fs/promises").then(({ writeFile }) => writeFile("screenshot.png", image));
For the authoritative request schema and current option names, use the Browserless Screenshot API documentation. Browserless marks its older BaaS v1 screenshot page deprecated; use the current REST API documentation for new integrations.
Useful Browserless capture options
Use the current API schema as the source of truth for exact accepted fields. The options below are useful when shaping a capture:
- Capture area: choose full-page capture for a long document, selector capture for one element, or clipping for a specific rectangle. A viewport screenshot captures only the visible browser area.
- Image encoding: select PNG, JPEG, or WebP where supported. Use a quality value where the format and API support it; lossy formats can reduce output size, while PNG is useful when preserving crisp edges matters.
- Viewport and scale: set viewport dimensions and device scale to control layout and pixel density. A higher scale can substantially increase image dimensions and response size.
- Wait behavior: configure navigation and wait conditions for pages that render asynchronously. Prefer waiting for a known selector when the desired content has a clear readiness signal; fixed delays can waste time or still be too short.
- Lazy-loaded content: Browserless documents
scrollPageto trigger content that loads during scrolling. Its docs recommend scrolling before capture when lazy loading is involved. - Request filtering: request rejection controls can block selected requests. Use them carefully: blocking scripts, fonts, or APIs that the page needs can change the rendered result.
- Input source: provide either
urlor inlinehtml. The docs warn not to include both in one request. - Page interaction: when a one-shot REST request is not enough, connect through the documented WebSocket flow with Puppeteer or Playwright, perform the needed actions, then capture.
Examples of the supported schema evolve. Check the current endpoint docs before copying additional fields into production code.
Cloudinary’s role after capture
If your workflow needs Cloudinary for media handling, the documented sequence is to create or obtain the screenshot, then use Cloudinary’s media APIs to manage and transform the resulting asset. Its image transformation documentation covers URL- and SDK-based transformations; its API overview describes media management and delivery.
For screenshot generation within Cloudinary, confirm that the URL2PNG Website Screenshots add-on is enabled and that url2png is available for your account. Do not assume the add-on has the same controls as a general browser automation API; verify the options your use case requires before committing to it.
Cloudinary states that transformation operations count toward plan usage. That affects the cost model after capture: estimate screenshot generation, transformations, storage, and delivery against the current account plan. The cited documentation does not provide a directly comparable Browserless-versus-Cloudinary screenshot price or quota, so check each vendor’s current plan and add-on terms.
Reliability, performance, and cost considerations
- Rendering time: dynamic pages may need fonts, client-side scripts, API responses, or user interaction before they are ready. Waiting on a stable page condition is generally more reliable than choosing an arbitrary delay.
- Long pages: full-page captures can take longer and produce larger files than viewport captures. Lazy images may not load until scrolled into view; use the documented scroll behavior where needed.
- Output size: viewport, scale, and image format all affect bytes returned and downstream storage or transfer. Choose the smallest dimensions and format that preserve the detail your application needs.
- Bot defenses: a CAPTCHA, blank result, or access-denied page can mean the target is blocking automated browsing. Browserless documents an
/unblockAPI for such cases, but that is a vendor-described capability, not a guarantee that a protected page will be captured successfully. - Retries: retry transient transport and service errors with a bounded retry policy and backoff. Avoid blindly retrying deterministic failures such as an invalid URL, rejected authentication, or a target that consistently returns a CAPTCHA.
- Budget: compare the current Browserless plan and usage unit with Cloudinary’s current plan, transformation usage, and URL2PNG add-on terms. The research sources do not support a like-for-like price comparison.
- Combined pipeline: if you capture through Browserless and then upload to Cloudinary, account for both stages, including image transfer, transformation usage, and storage or delivery requirements.
Common errors and fixes
| Symptom | Likely cause | What to check |
|---|---|---|
| Request rejected or unauthorized | Missing, invalid, or incorrectly placed Browserless token | Confirm the token query parameter and endpoint host match your Browserless account configuration. |
| JSON or request validation error | Malformed JSON or fields that do not match the current REST schema | Send a JSON body with the correct content type and verify option names in the current endpoint docs. |
| Unexpectedly blank or incomplete screenshot | Capture began before client-rendered content was ready, or content is lazy-loaded | Wait for the relevant selector or page condition; use the documented scroll behavior for lazy content. |
| Only the visible portion appears | Viewport capture was requested instead of full-page capture | Enable the documented full-page option and check whether the target’s layout or sticky elements affect the result. |
| Element capture is empty | The selector did not match, appeared late, or is hidden | Check the selector against the rendered DOM and wait for the target element before capture. |
| CAPTCHA or access-denied image | The target site detected or blocked automated access | Review Browserless’s documented /unblock option and the target site’s access rules; success is not guaranteed. |
Cloudinary url2png unavailable |
The required URL2PNG add-on is not enabled or available on the account | Confirm current add-on access and terms with Cloudinary before relying on this delivery type. |
| Unexpected Cloudinary usage | Image transformations contribute to plan usage | Review current usage and plan details, including all transformations in the pipeline. |
Or skip the browser setup
ScreenshotNeo is a direct screenshot API and MCP server. One GET request takes a URL and returns an image or PDF; its docs list full-page capture, CSS selector capture, viewport and device settings, waits, custom headers and cookies, blocking controls, caching, async jobs, and bulk capture. See the ScreenshotNeo API documentation for the request options.
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}`);
- Cookie banners, newsletter 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 not billed. Responses identify the page verdict and billing outcome.
- An MCP server gives AI agents such as Claude, Cursor, and other MCP clients screenshot, page-info, and PDF capture tools.
- The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up free for 1,000 screenshots a month, with no card required.
FAQ
Can Cloudinary take website screenshots?
Yes. Cloudinary documents the url2png delivery type, which requires the URL2PNG Website Screenshots add-on. Confirm availability and billing for your account.
Does Browserless return an image or a URL?
The documented REST screenshot request returns image data in the response. Save the response body as a file or pass it to your next processing step.
Can I use Cloudinary and Browserless together?
Yes, if your architecture benefits from browser-based capture followed by Cloudinary asset management, transformations, or delivery. Account for each service’s current usage terms.
Which should I choose if I need browser interaction?
Browserless documents WebSocket connections through Puppeteer and Playwright for workflows that need more control than a single REST screenshot request.
