ScreenshotNeo

BlogHow-to

How to Make Asynchronous Screenshot API Requests for Long Pages

Submit long-page screenshot jobs, poll safely, and retrieve complete results. Learn how full-page capture, JavaScript waits, lazy loading, and failures affect output.

By the ScreenshotNeo team4 October 20269 min read

To make an asynchronous screenshot API request for a long page, submit a capture job, save its job ID or status URL, poll the provider’s documented status endpoint until the job completes or fails, then retrieve the result using the provider’s documented method. Enable full-page capture if you need the entire scrollable page, and configure render waits or lazy-load handling when the page depends on JavaScript or content loaded during scrolling.

There is no universal screenshot API endpoint, request shape, polling interval, page-height limit, or result-retention period. Check the chosen provider’s current API reference for authentication, limits, status values, retry rules, and how long completed results remain available.

1. Understand full-page scope and asynchronous jobs

A viewport screenshot captures the visible browser area. A full-page screenshot captures the page’s full scrollable extent. Playwright exposes this distinction with its fullPage screenshot option; a provider may expose a different parameter or behavior. See the Playwright screenshot documentation.

Asynchronous capture separates submission from result retrieval. The submission call can return before rendering finishes, with a job ID or status URL to use for later checks. The documented Allscreenshots .NET example follows create, check status, and retrieve result stages; its SDK, endpoint, fields, and behavior are specific to that provider. See the Allscreenshots .NET SDK documentation.

2. Check provider behavior before writing the client

Before implementing a production workflow, record these details from the provider’s current reference:

  • Authentication method, accepted URL schemes, and whether redirects are followed.
  • How to request a full-page image, set the viewport and output format, and configure navigation or selector waits.
  • Maximum page height, image dimensions, request duration, concurrency, and account quotas.
  • Whether submission is always asynchronous or can return an immediate result or an error.
  • The status endpoint, exact terminal success and failure states, recommended polling cadence, and rate limits.
  • How to retrieve the result, which formats are available, and when the result expires.
  • Whether retries can create duplicate jobs, and whether the service supports idempotency keys or cancellation.

These details vary. For example, Cloudflare documents navigation wait options and warns that JavaScript-heavy sites and SPAs can be incomplete with default loading behavior. See Cloudflare Browser Run documentation. Do not assume that a setting or behavior from one service applies to another.

3. Implement the create, poll, and retrieve workflow

  1. Build the capture request. Include the target URL, full-page setting, intended viewport and format, and a supported wait condition appropriate to the page.
  2. Submit the job. Check the HTTP status and parse the provider’s response. Persist the job ID or status URL before polling so a process restart does not lose track of the capture.
  3. Poll for a terminal state. Follow the provider’s polling guidance and rate limits. Continue on documented nonterminal states; stop on documented success or failure. Use a bounded overall deadline.
  4. Retrieve and validate the result. Download the completed image through the provider’s result mechanism. Check the response status, content type, file size, and whether the image contains expected content near the bottom of the page.
  5. Handle failure and expiry. Record the provider’s error details. If the result expired, submit another capture only if that is appropriate; avoid blind retries that could create duplicate jobs or charges.

The code below is deliberately provider-neutral pseudocode. Replace the endpoint paths, authentication, fields, status values, and result handling with the chosen API’s documented contract. It demonstrates the control flow, not a real universal API.

POST {provider_submit_endpoint}
Authorization: {provider_authentication}
Content-Type: application/json

{
  "url": "https://example.com/article",
  "full_page": true,
  "viewport": { "width": 1440, "height": 1000 },
  "format": "png",
  "wait_until": "{provider_supported_wait_condition}"
}

# Example response shape only; use the provider's actual fields.
{
  "job_id": "{provider_job_id}",
  "status_url": "{provider_status_url}"
}

GET {provider_status_url}
Authorization: {provider_authentication}

# Repeat at the provider's documented cadence until a terminal state.
# On documented success, request the documented result URL or endpoint.
GET {provider_result_url}
Authorization: {provider_authentication}

Do not copy the illustrative JSON field names as though they were standardized. Some services return a URL, some return an ID, and some switch between synchronous and asynchronous behavior depending on the request. The pageops documentation describes sync-to-async fallback behavior for its service; check its current API reference for the actual conditions and response format: pageops documentation.

4. Make long-page captures complete

Full-page mode requests a larger capture area, but it does not guarantee every element has loaded. Long pages commonly combine content below the fold, images loaded on scroll, client-side rendering, and delayed widgets. A screenshot can finish successfully while still omitting content the page had not rendered.

Use an appropriate render wait

Use a provider-supported navigation wait, selector wait, or explicit delay based on how the target page works. A navigation event alone may not mean an SPA has finished fetching and rendering its main content. Waiting for a stable page-specific selector is often more targeted than adding a large fixed delay, when the API supports selector waits. Avoid waiting for complete network silence unless the provider and page make that reliable; analytics, polling, or streaming requests can keep a page active.

Account for lazy-loaded content

Some pages load images or sections only after a scroll reaches them. Check whether the provider scrolls the page before capture or offers controls such as scroll intervals, maximum height, section count, or a timeout. Allscreenshots describes such controls in its guide, but they are provider-specific: Capturing full-page screenshots.

If the API does not handle lazy loading, alternatives depend on the provider: use a browser automation workflow that scrolls through the page before capturing, or capture defined sections and combine them if the provider supports it. Set explicit height or section bounds when available so a very long or endlessly growing page does not consume unbounded time or produce an unusable image.

Validate the bottom of the image

For representative URLs, inspect the returned image near the bottom and check for missing images, placeholders, repeated sections, cut-off content, blank pages, and error screens. A successful HTTP response or completed job indicates the capture operation completed; it does not prove that every dynamic element rendered correctly.

5. Polling, timeouts, and retries

  • Honor documented cadence and limits. Polling too frequently wastes requests and may hit rate limits. Use the provider’s recommended interval, any retry-after value, and its quota guidance.
  • Set an overall deadline. Bound the whole job, including submission, queue time, rendering, and result download. A client timeout does not necessarily cancel a server-side job.
  • Use backoff only where allowed. If the provider permits it and gives no stricter cadence, increase the delay between transient polling errors rather than retrying rapidly. Add jitter when many jobs run together to avoid synchronized bursts.
  • Retry the right operation. A failed status read may be safe to retry; resubmitting capture after an ambiguous submission timeout may create a second job. Use provider-supported idempotency or first reconcile the original job if possible.
  • Persist enough state. Store the job identifier, submission time, target reference, last observed state, and result expiry if returned. Avoid storing credentials with the job record.
  • Stop on terminal failure. Preserve the provider’s error code and message for diagnosis. Do not poll a terminal job forever.

6. Performance, reliability, and cost

Longer pages, larger viewports, full-page output, and JavaScript-heavy rendering can increase render time and image size. The actual limits and charges depend on the provider and plan; the research sources do not establish a common benchmark or shared pricing model. Measure your own representative URLs and formats, and confirm how failed jobs, retries, and asynchronous work are billed.

For throughput, bound concurrent jobs to the provider’s documented limits. Keep submission and polling separate so a worker can resume a job after a process restart. Set a maximum capture height or section count where supported, and store large results in an appropriate destination rather than holding many image buffers in memory. Monitor time from submission to terminal state, failure categories, result expiry, and the fraction of images that fail content validation.

For reliability, treat transport success, job success, and useful rendered content as separate checks. A submission can succeed while rendering later fails; a render can succeed while the page itself shows a bot check, blank state, or application error. Validate outputs for the pages that matter to your workflow.

7. Troubleshooting

Symptom Likely cause What to do
Submission times out and no job ID is received The request may have reached the provider even though the client timed out. Check for provider-supported idempotency or a way to reconcile recent jobs before resubmitting. Do not assume the first request was canceled.
Status polling returns an error or rate limit Wrong status URL or authentication, excessive polling, or expired job. Verify the provider’s response fields and credentials; obey its cadence and retry-after instructions; check job lifetime.
Job stays queued or rendering for a long time Queue delay, expensive page, stalled navigation, or an unsuitable wait condition. Check provider status details and documented time limits. Use a bounded deadline, then retry only according to provider guidance.
Capture finishes but lower sections are missing Viewport capture was requested, page height was capped, or lazy-loaded content never activated. Confirm full-page mode and height limits. Enable provider-supported scrolling or capture sections; inspect the bottom of the result.
Images or application data are missing Lazy loading, JavaScript rendering, or capture before a required element appeared. Use supported navigation or selector waits and lazy-load handling. Test the page’s actual render sequence.
Image is blank or shows an error page Navigation failure, blocked access, bot check, or client-side application error. Inspect provider diagnostics and the returned image. Check that the URL is publicly reachable from the provider’s browser and that required headers or cookies are configured.
Result URL no longer works Provider result retention expired or the URL is temporary. Retrieve and store results promptly; confirm retention and signed URL expiry in the provider reference.
Output is unexpectedly huge or truncated Unbounded page height, image dimension limits, or provider-specific full-page constraints. Set a maximum height or section count if available, reduce viewport or scale, or capture the page in bounded sections.

8. Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. For a long page, one GET request can return a screenshot; full-page capture loads lazy images. See the ScreenshotNeo API documentation for the supported parameters and response behavior.

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 responses include X-Page-Verdict and X-Billed headers. Its MCP server gives AI agents, including Claude and Cursor, the take_screenshot, get_page_info, and capture_pdf tools. The Free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots.

Create a free ScreenshotNeo account for 1,000 screenshots a month with no card.

9. FAQ

Does asynchronous capture make a screenshot more complete?

No. Async changes when you receive the result. Completeness still depends on capture scope, rendering waits, page behavior, and lazy-load handling.

Can I use one polling interval for every API?

Use the interval and rate-limit guidance from the provider you selected. There is no universal cadence.

Should I wait for network idle on every page?

No. Choose a supported wait that matches the page. Background requests can prevent network idle, while a page can also become quiet before its main content is ready.

How can I tell whether a completed capture is useful?

Check the image itself, especially content below the fold, and validate it against expected page elements. Job completion alone does not guarantee complete rendering.