ScraperFlyAI-ready Web Data API

rendering

Headless Browser Scraping API for public JavaScript pages

Headless browser scraping is useful when raw HTML is not enough, but browser infrastructure can become expensive and fragile if every request uses it by default. ScraperFly lets teams turn rendering on for public pages that need browser execution, while keeping simple targets light and preserving outputs that downstream workflows can parse, review, or archive.

Hosted browser capture

Get the rendered page state without owning browser infrastructure

ScraperFly gives teams a hosted browser layer for public pages that need real rendering. Capture the page after JavaScript has run, inspect the evidence, and choose the output your product can actually use.

Keep simple targets on lightweight HTML requests, then reserve browser execution, waits, screenshots, PDFs, sessions, or stronger delivery for pages where they make the result better.

rendered DOMvisual proofcontrolled browser work
Developer validating a rendered public page capture with hosted headless browser output

When does scraping need a headless browser?

Scraping needs a headless browser when the useful public page content is created after the first HTML response. Many modern pages return a thin shell with script tags, then build products, articles, dashboards, prices, comments, route views, or search results in the browser. A basic HTTP fetch can return a successful status code and still miss the data your workflow expects.

The first job is not to launch a browser by habit. The first job is to prove where the content lives. If source HTML already contains the required fields, links, text, or tables, a raw HTML request is usually the better default. If the browser changes the DOM in a meaningful way, rendering becomes useful. If the browser displays the wrong state, a fallback page, or missing lazy content, waits, sessions, headers, or routing may need to be tested next.

Practical takeaway: use headless browser scraping for public pages where browser execution reveals useful content that a simple HTML request cannot capture.

What does ScraperFly replace in a browser scraping stack?

Running headless browsers in production is not just a Playwright or Puppeteer script. Teams have to schedule browser workers, control concurrency, handle timeouts, rotate delivery paths, manage memory, preserve cookies when needed, wait for late content, capture screenshots or PDFs, store logs, and decide when a failure deserves a retry. That infrastructure can become more complicated than the data workflow it was meant to support.

ScraperFly gives teams a hosted API layer for this capture work. Your application sends the public URL and a request profile. ScraperFly can fetch source HTML, render the page in a browser when needed, wait for content, return rendered HTML, convert the response to text or Markdown, expose JSON metadata, or produce screenshot and PDF outputs for review. Your product still owns parsing, validation, storage, alerts, and business logic, but it no longer has to operate browser infrastructure just to test whether a target page can be captured.

Production concern Own browser stack ScraperFly API path Decision value
Browser workers Provision, update, restart, and monitor browser processes Enable rendering as a request option Use browser work without turning it into a platform project.
Late content Write custom waits and timing rules per target Test render and wait controls against real samples Keep timing decisions tied to evidence from the page.
Output conversion Build converters for HTML, text, screenshots, and PDFs Choose the response format the workflow needs Reduce glue code before downstream parsing or QA.
Failure recovery Diagnose timeouts, blocks, redirects, shells, and blank captures manually Use response evidence, status, size, final URL, and artifacts Retry or escalate based on a clear failure signal.

How should teams decide between raw HTML and rendered output?

The safer workflow is to compare before you commit. Start with source HTML because it is lighter, easier to inspect, and often enough for server-rendered pages, static pages, metadata, links, or tables. Then run a rendered request for representative targets where raw HTML looks empty, thin, or inconsistent with the page in a browser. Compare the body size, meaningful text, expected selectors, status code, final URL, content type, and any visual artifact.

This comparison prevents two common mistakes. The first mistake is rendering everything and paying browser cost even when a simple request already works. The second is refusing to render a JavaScript page and then building fragile downstream fixes around incomplete data. ScraperFly is useful because both paths stay in one API workflow: raw HTML for simple targets, browser rendering for pages that prove they need it.

Page evidence Best first action Escalate when Practical takeaway
Source HTML contains the data Keep render disabled The target starts hiding content or changing output Do not pay browser cost when markup is already usable.
Source HTML is only an app shell Enable browser rendering Rendered output still misses expected content Use the browser when JavaScript builds the useful state.
Rendered page loads content late Add a measured wait More samples prove timing is unstable Wait for evidence, not for a guessed number of seconds.
Rendered HTML and screenshot disagree Inspect final URL, status, and page state The target returns a fallback or blocked view Visual proof helps separate missing data from wrong page state.

Which output should a headless browser request return?

Rendered HTML is the natural output when a parser needs DOM structure after JavaScript execution. It preserves elements, links, attributes, tables, and page relationships. Text is better when the downstream workflow needs compact readable content. Markdown is useful for AI, RAG, documentation, and content review because headings, lists, and links remain easier to consume. JSON metadata helps logging and debugging by exposing request evidence such as final URL, status, content type, and response details.

Screenshots and PDFs are not replacements for parsable content. They are evidence formats. Use them when a human needs to verify what the browser saw: a rendered product page, visual regression, compliance record, approval state, monitoring proof, or archived page view. They are heavier than text and HTML, so they should be requested when visual proof matters, not as the default for machine-only workflows.

Practical takeaway: choose rendered HTML for parsers, text or Markdown for content pipelines, metadata for diagnostics, and screenshots or PDFs when visual proof has real value.

What makes headless browser scraping fail?

Browser scraping can fail even when the API request itself is valid. The target can load slowly, redirect to a different page, return an empty shell, serve a challenge or fallback view, block automation, send a response that is too large, or never expose the expected content for that request context. Retrying blindly can make the same bad request more expensive without moving the workflow closer to a usable result.

The better path is diagnosis. Check whether the URL is correct, whether source HTML is thin, whether rendered output changed, whether the final URL is expected, whether the response size looks plausible, whether the screenshot proves the right page state, and whether headers, sessions, waits, country routing, or premium delivery are relevant. The error-handling block below expands that recovery model, but the main rule is simple: fix configuration errors, retry temporary failures with limits, and escalate delivery only when the evidence points there.

How does ScraperFly keep browser scraping cost under control?

Headless browser work is heavier than a simple HTML fetch because it runs a browser environment and may involve waits, rendered state, visual output, or stronger delivery. That extra work can be worth it, but only when it improves the captured result. ScraperFly keeps the cost model practical by letting teams start light, compare responses, and reserve rendering for public pages that prove a browser is necessary.

This matters most before scaling. A team can test representative pages, identify which targets need rendering, decide which ones need screenshots or PDFs, and keep simple pages on cheaper request profiles. That turns browser rendering from an all-or-nothing architecture choice into a controlled request decision.

Where should a developer start?

Start with the API Builder. Test a public URL with rendering off, inspect the response, then enable rendering if raw HTML does not contain the useful content. If the page needs browser execution, compare the output formats before writing converters. Use JavaScript rendering API guidance for broader rendering decisions, response formats for output selection, and pricing when estimating request weight before a larger run.

Once the request profile is proven, copy it into cURL, Postman, Python, Node.js, a backend worker, an agent, a monitoring job, or a parser pipeline. The goal is not to use a browser for every scrape. The goal is to use a browser exactly where it turns an incomplete public page response into usable evidence.

Headless browser scraping

Use a browser only when the target needs real rendering

Headless browser scraping is valuable when important content appears after JavaScript, user interaction, redirects, or async loading. ScraperFly helps teams test the target first, compare raw HTML with rendered output, and reserve browser work for pages where it changes the result.

Raw HTML response mapped to visible page data
01

Raw HTML availability

Check whether the fields you need are already present in the first HTML response.

Best first test for simple pages, articles, docs, listings, and product details.

Before and after JavaScript rendering comparison
02

JavaScript dependency

Compare raw HTML with the rendered DOM or screenshot before turning on browser rendering.

Use rendering when raw HTML is only a shell and scripts create the useful content.

Cookies, consent, session and access context for scraping
03

State & access context

Identify whether cookies, consent, login boundaries, pagination, or the same visitor state affect the response.

Use sessions and headers when continuity changes the data you receive.

Regional content variations across countries and routes
04

Geo/content variation

Test whether country, language, currency, inventory, SERP, ads, or route reputation changes the result.

Use geo or premium routing only when the target proves the response varies by route.

Checks before using a headless browser

Where is the target field?

Find whether the field exists in raw HTML, rendered DOM, an API call, structured data, a file, or a later interaction state.

What changes the response?

Sample a few URLs and compare status, final URL, content length, redirects, empty states, and visible result differences.

What context is required?

Mark any dependency on consent, locale, cookies, headers, authentication boundary, pagination, filters, or previous requests.

What does failure look like?

Define the signals for blocked, partial, stale, redirected, empty, timed-out, or region-mismatched responses before scaling.

How browser requirements change the request

Fetch mode

Raw HTML availability decides whether the first request can stay simple or needs rendering, waits, screenshots, or extraction.

Request context

State requirements decide whether to add headers, cookies, sessions, consent handling, or a stable visitor profile.

Routing choice

Geo and reputation findings decide whether standard routing is enough or a country/premium route is justified.

Validation rules

Known failure states become checks for retries, escalation, QA review, and deciding when a lighter profile is still complete.

Browser request builder

Build a rendered scraping request without turning every job into a heavy browser run

Start with a lightweight request, then add browser rendering, waits, sessions, headers, country routing, premium delivery, screenshot, or PDF output when real samples prove the page needs them.

HTML
First pass

Check source HTML before launching the browser

Some pages already expose data in markup, metadata, script payloads, or server-rendered content.

render=falseformat=html
JS
Rendered DOM

Render pages that build content in the browser

Browser execution helps capture client-side apps, lazy sections, route states, and data that appears after JavaScript runs.

render=truewaits
QA
Visual proof

Capture screenshots or PDFs when humans need evidence

Visual outputs help verify page state, layout, missing content, and review-heavy workflows.

screenshotpdf

Controls that matter for headless browser scraping

url

The public page or route being captured.

render

Browser execution for JavaScript-built pages.

wait

Timing control for async content and lazy sections.

format

HTML, text, Markdown, JSON, screenshot, or PDF output.

cURL example

Generate Markdown with the same request shape you can move into production

curl "https://scraperfly.com/api/v1?url=https%3A%2F%2Fexample.com&format=markdown" \
  -H "apikey: YOUR_API_KEY"

Error handling

Turn scraping failures into fixes

Every web data workflow eventually meets a bad response: a missing URL, an invalid key, an empty HTML shell, a target 403, a rate limit, a render timeout, a broken PDF capture, or a JSON payload that does not contain the fields your product expected. ScraperFly is built to make those moments diagnosable. You inspect the HTTP status, the stable error code, the request profile, and the returned artifact, then choose the cheapest useful next move: fix the request, add credits, slow down, retry with backoff, enable rendering, change country, use premium routing, preserve headers, or validate the output before scaling.

Stable error shapeRetry decisionsCost-aware escalationOutput validation
Developer reviewing code and API request parameters on a laptop

01 / Request setup and access

Fix request mistakes first

Some failures are not target problems at all. They happen before ScraperFly can make a meaningful delivery attempt: a missing or malformed URL, an unsupported output format, an incompatible visual file type, a missing API key, an invalid key, or a key that has been paused or disabled. These errors are configuration signals, not retry signals: stop the workflow, point the developer to the exact field that needs correction, and keep credits focused on real target tests instead of repeated bad inputs.

missing_urlinvalid_urlunsupported_formatinvalid_api_key
  • Validate the URL and encoding before sending a batch.
  • Use supported outputs: HTML, text, Markdown, JSON, screenshot, or PDF.
  • Match screenshot file types to image output and PDF file type to PDF output.
  • Treat missing or invalid API keys as configuration work, not retry work.
Business dashboard with charts, documents and usage planning on a desk

02 / Credits, limits and concurrency

Separate limits from failures

A workload can fail because the account has no usable credits, the monthly plan limit has been reached, or concurrency is too aggressive for the current plan and target mix. ScraperFly makes those limits visible as operating signals, not mysterious scrape failures. That keeps the buying decision practical: start free, test the target, buy pay-as-you-go credits for uneven jobs, move to monthly credits when volume becomes predictable, and use backoff when request pressure is the real issue.

usage_limit_reachedrate_limitedcreditsbackoff
  • Use account status to check remaining credits before large runs.
  • Retry rate limits with backoff instead of immediately increasing pressure.
  • Keep one-off projects on pay-as-you-go when volume is uneven.
  • Move predictable recurring work to monthly credits when the pattern is proven.
Server room representing delivery paths, routing and network infrastructure

03 / Target delivery and network

Find delivery failures first

Many scraping platforms collapse delivery issues into a vague request failure. In production, that is not enough. The team needs to know whether the request timed out, the upstream target returned a temporary server error, the connection failed, the response was too large, redirects went somewhere unexpected, or the page came back as tiny HTML with no useful content. ScraperFly turns those failures into delivery evidence: try the light profile first, compare status and response size, then decide whether the next request needs backoff, another route, premium proxy, country targeting, or a narrower capture.

timeout5xxredirectsresponse_too_large
  • Retry temporary network and upstream failures with a controlled backoff policy.
  • Compare final URL, status, content type and response size across samples.
  • Escalate routing only when the response proves the simple path is unstable.
  • Treat oversized responses as a scope problem before scaling the same profile.
Digital security screen representing anti-bot and protected access signals

04 / Anti-bot, geo and access blocks

Read blocks before escalation

A target 403, 401, 429, CAPTCHA screen, WAF challenge, login wall, consent loop, or region-specific mismatch is not just an error; it is a clue about what the site expects from the visitor. Competitors often push teams toward a heavier default profile, but that can burn budget without proving the fix. ScraperFly's better path is evidence-based escalation: preserve realistic headers when context matters, use sessions when continuity changes the response, enable rendering when the useful content is browser-built, and choose premium or country routing when reputation or geography changes the result.

403429CAPTCHAcountry mismatch
  • Use premium routing when IP reputation is the proven bottleneck.
  • Use country targeting when language, currency, inventory or search results change by market.
  • Use headers, cookies and sessions when visitor state changes the response.
  • Reduce concurrency and add backoff when repeated requests trigger target throttling.
Developer preparing code and output artifacts on a laptop

05 / Rendering and output quality

Ship usable artifacts

A 200 status is not the same thing as a usable scrape. The raw HTML can be an empty app shell, Markdown can miss the main article, JSON can lack expected metadata, text can include noise, screenshots can be blank, and PDF or image output can fail if the browser step times out. ScraperFly is valuable because the same API request can move from raw HTML to rendered DOM, clean text, Markdown, JSON, screenshot or PDF, then be checked against the artifact your product actually needs. That reduces glue code, failed imports, and expensive batch runs that only discover bad output after the fact.

render_timeoutbrowser_render_failedJSON fieldsPDF/image output
  • Enable rendering when raw HTML is only a shell and the useful content appears after JavaScript.
  • Validate text, Markdown and JSON against expected fields before batching.
  • Use screenshot or PDF output when visual proof or audit evidence matters.
  • Treat blank or partial artifacts as quality failures even when HTTP status is successful.
ScraperFly fit

Cleaner error recovery

ScraperFly helps teams decide what to fix, what to retry, and what to escalate without turning every scrape into the most expensive request profile.

Stable error shape

Use HTTP status and error code together so application logic can choose between fixing input, refreshing credentials, slowing down, retrying, or escalating delivery.

Retry only when it helps

Network failures, rate limits, and temporary server errors can use backoff. Invalid URLs, unsupported formats, and bad keys should be corrected once.

Cost-aware escalation

Start with the light request profile, then add rendering, premium routing, country, sessions, headers, waits, or visual capture only when the failure proves it.

Validate output before scale

Confirm the real artifact your product needs: HTML, text, Markdown, JSON, screenshot, or PDF, before copying the same profile across a large URL set.

Browser cost

Control rendering cost by proving the browser adds value

Headless browsing is powerful but heavier than simple HTML capture. ScraperFly keeps teams cost-conscious by letting them compare output before making rendering the default.

A lightweight HTML request returning a simple response
01

Basic fetch

Use a basic fetch when public HTML already contains the fields you need.

Lightest request profile; keep it when the response is complete.

JavaScript rendering producing a complete DOM
02

Rendering

Use rendering when raw HTML is a shell and JavaScript completes the page.

Heavier profile; use it only when browser output changes the result.

Several requests preserving cookies and visitor state
03

Stateful session

Use sessions when cookies, consent, locale, or pagination change the response.

Heavier state profile; preserve it only when continuity matters.

Request routing through geo and higher quality routes
04

Premium routing & geo

Use premium routing or geo only when origin, country, reputation, or regional content changes the result.

Heaviest routing profile; apply it only to targets that prove they need it.

What makes browser scraping heavier

More infrastructure work

Browser rendering, routing choices, and longer waits mean the platform has to do more than return a simple response.

More target uncertainty

Redirects, empty states, rate limits, and challenge pages often require stronger delivery options or retries.

More state to preserve

Cookies, sessions, consent, and multi-page flows add moving parts that a plain stateless fetch does not have.

More evidence to return

Screenshots, PDFs, rendered output, and richer response artifacts are useful, but they are heavier than plain HTML.

How to keep rendered scraping predictable

Sample before scale

Test a small URL set first and group targets by the lightest profile that returns complete data.

Do not render by default

Inspect raw HTML before turning on rendering. Many public pages already contain the data you need.

Escalate by evidence

Move up only when the response shows missing content, state dependency, geo variance, or routing problems.

Measure useful results

Optimize around valid records delivered, not raw request volume. A lighter profile is best only when it stays complete.

Browser questions

Common questions about headless browser scraping

Practical answers for teams deciding when browser rendering is worth using, how to choose output formats, and how to avoid turning every scrape into a heavy request.

Browser FAQ
Rendering

When to use the browser

Use browser execution when it changes the captured result.

Should every scraping request use a headless browser?

No. Start with source HTML and enable rendering only when JavaScript creates the useful content or the workflow needs visual proof.

How do I know raw HTML is not enough?

Compare the source response with rendered output. If source HTML is a thin shell or misses expected content that appears after browser execution, rendering is justified.

Output

Formats after rendering

Rendered pages can still serve different downstream needs.

Which output format should I request after rendering?

Use rendered HTML for parsers, text or Markdown for readable content workflows, JSON metadata for diagnostics, and screenshots or PDFs for visual proof.

Are screenshots and PDFs good parser inputs?

Usually not. They are best for QA, monitoring, approvals, and archives. Machine parsing is usually easier from HTML, text, Markdown, or structured metadata.

Recovery

Failures and cost control

Browser failures need evidence before retries or escalation.

What should I inspect when a rendered request is empty?

Check final URL, status, response size, source HTML, rendered HTML, screenshot state, wait timing, and whether the target returned a fallback or blocked page.

Does rendering always cost more than simple HTML capture?

Browser work is heavier than a basic fetch. Keep simple pages on raw HTML and reserve rendering, waits, screenshots, PDFs, and premium delivery for targets that prove they need them.

Production

From test to stable workflow

A proven browser request should move into production with clear limits.

How should I move a rendered request into production?

Test the public URL in API Builder, confirm the smallest useful output, then copy the proven request profile into your backend, job runner, monitor, or agent workflow.

When should I add waits, sessions, or premium routing?

Add them only after response evidence shows they improve the result: waits for late content, sessions for shared state, and premium routing for repeated delivery problems.