PageCrawl.io Screenshot API Returning a Blank Image: Fixes to Try
Find out whether PageCrawl captured a blank page or your client failed to retrieve the screenshot, then fix the likely cause.
A blank image from PageCrawl can mean two different things: the stored capture itself is blank, or the capture is fine but your application cannot retrieve or display it. Check the screenshot inside PageCrawl first. If it is blank there too, investigate the page load and capture setup. If it looks correct there, investigate the screenshot request, webhook payload, authorization, and image handling in your client.
PageCrawl documents screenshot retrieval as part of its website-monitoring API. The documented route for a specific check is GET /api/pages/{id}/checks/{checkId}/screenshot. Use PageCrawl’s Developer mode to copy the exact URL and request for the page and check you are inspecting; do not guess IDs or copy options from another screenshot vendor. See the PageCrawl API developer guide and its API reference.
1. Identify which screenshot failure you have
| What you find | Likely problem | Start here |
|---|---|---|
| The screenshot is blank or shows an error in PageCrawl too | The monitored page did not render as expected, access was denied, or the check captured before content was ready. | Inspect the check status and error, then check the target URL, access, timing, browser engine, JavaScript, location, and page actions. |
| The screenshot looks right inside PageCrawl, but your application shows a blank image or cannot load it | The screenshot request, credentials, webhook fields, URL handling, response, or client rendering is wrong. | Copy the exact page/check request in Developer mode, then inspect the HTTP response and image rendering. |
Open the exact page and check associated with the failing request. Compare the stored image with the image your application displays, and note the check status and any error. A URL being returned does not prove that its image contains the expected page.
2. Retrieve the exact stored screenshot
Enable Developer mode under Settings > API. PageCrawl exposes page and check IDs and copyable API requests there, including screenshot and visual-diff requests. Copy the screenshot request for the check you are diagnosing. The endpoint documented for a particular page and check is:
GET https://pagecrawl.io/api/pages/{id}/checks/{checkId}/screenshot
Authorization: Bearer YOUR_API_TOKEN
Replace {id} and {checkId} with the exact IDs shown by PageCrawl. The examples below use placeholders; use the exact URL from Developer mode if the dashboard presents a different request shape. PageCrawl documents Bearer-token authentication for REST API requests in its API and webhooks guide.
cURL
curl --fail-with-body --location \
"https://pagecrawl.io/api/pages/PAGE_ID/checks/CHECK_ID/screenshot" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-o pagecrawl-check.png
Use the route copied from Developer mode. If the response is JSON or HTML rather than image bytes, save or inspect that response instead of assuming the command downloaded a screenshot. Check the HTTP status and Content-Type.
Python
import requests
url = "https://pagecrawl.io/api/pages/PAGE_ID/checks/CHECK_ID/screenshot"
response = requests.get(
url,
headers={"Authorization": "Bearer YOUR_API_TOKEN"},
timeout=60,
)
response.raise_for_status()
content_type = response.headers.get("Content-Type", "")
if not content_type.startswith("image/"):
raise RuntimeError(
f"Expected image bytes, got {content_type}: {response.text[:500]}"
)
with open("pagecrawl-check.png", "wb") as image_file:
image_file.write(response.content)
Node.js
const url = "https://pagecrawl.io/api/pages/PAGE_ID/checks/CHECK_ID/screenshot";
const response = await fetch(url, {
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
signal: AbortSignal.timeout(60_000),
});
if (!response.ok) {
throw new Error(`Screenshot request failed: HTTP ${response.status}`);
}
const contentType = response.headers.get("content-type") ?? "";
if (!contentType.startsWith("image/")) {
const body = await response.text();
throw new Error(`Expected an image, got ${contentType}: ${body.slice(0, 500)}`);
}
const bytes = Buffer.from(await response.arrayBuffer());
await import("node:fs/promises").then(fs => fs.writeFile("pagecrawl-check.png", bytes));
These examples are for downloading a screenshot response. For a webhook, PageCrawl can provide page_screenshot_image as a URL in the JSON payload. That flow is different: first confirm your webhook includes that field, then fetch its URL as documented or as represented in the actual payload. Avoid logging bearer tokens or signed image URLs.
3. If the stored capture is blank, diagnose the page load
Open the same URL yourself
Load the exact target URL in a normal browser, including its path and query string. Check whether it is blank there, too. If it requires a login, consent, a particular region, or a preceding interaction, a screenshot setting alone cannot supply access that the check does not have.
- 401: The page or resource usually requires authentication. Confirm the intended login or access setup.
- 403: Access was refused. Permissions, site protection, or a bot challenge may be involved.
- 404: Verify the URL; the page may no longer exist at that address.
- 500-series response: The site may be unavailable, overloaded, or having a server problem.
- Timeout: The site may be slow or temporarily unresponsive, or the check may have reached its plan limit.
- CAPTCHA or bot challenge: Confirm the capture actually shows a challenge. A location change or connection option does not guarantee that a challenge will disappear.
PageCrawl’s page-loading troubleshooting guide lists check timeouts of 45 seconds on Free, 90 seconds on Standard, and 180 seconds on Enterprise and Ultimate. These are PageCrawl plan limits, not a promise that every target page will finish within that time.
Match the setting to the observed failure
Make one change at a time, run a new check, and inspect that check’s stored screenshot and status. Page adjustments and advanced configuration are described in PageCrawl’s advanced configuration guide and actions guide.
| Symptom | PageCrawl control to consider | How to use it |
|---|---|---|
| Content appears after the initial load | Wait for text or a fixed delay | Wait for a meaningful page-specific condition where available. Use a short, bounded delay only if the page has no suitable condition. |
| Content depends on scripts | JavaScript and browser engine | Check that JavaScript is enabled and use a real browser engine when the page needs browser behavior. Fast mode is intended for static pages. |
| Content appears after scrolling | Scroll to bottom, then Wait | PageCrawl recommends scrolling to load lazy content and waiting briefly afterward; its actions guide gives 2–3 seconds as an example. |
| Content appears only after clicking, typing, or navigating | Recorded actions | Configure the needed interaction before capture. Actions run in order, so place waits after interactions that need time to update the page. |
| Page differs by country or access route | Location or eligible connection options | Try a location that matches the intended visitor. A location setting does not provide credentials or guarantee that site protection will allow access. |
| Wrong tracked content or missing element | Tracked element selector | Inspect whether the selector still exists and whether it is present at the point the check extracts content. Update a selector that no longer matches. |
PageCrawl’s JavaScript actions run after page load and before extraction, require a real browser engine rather than Fast mode, and have a 30-second safety timeout. Keep custom scripts and polling bounded. Prefer a built-in click, wait, or scroll action for a simple interaction; use custom JavaScript only when the built-in actions do not cover the required setup. See PageCrawl’s JavaScript actions documentation.
Test CAPTCHA and bot protection carefully
First confirm that the captured page actually contains a CAPTCHA or bot challenge. PageCrawl documents a separately configured CAPTCHA integration for Enterprise and Ultimate. Its troubleshooting guidance also discusses connection options for eligible cases, but changing location or using Relay does not guarantee access to every protected site. Do not interpret a challenge page as a successful capture of the intended content.
4. If the stored capture is correct, debug retrieval and display
- Use the exact page and check IDs. IDs copied from a different monitor or check can return the wrong image or an error. Use the screenshot request exposed by Developer mode.
- Check authorization. REST API requests use
Authorization: Bearer YOUR_API_TOKEN. Check that the token is present, current, and permitted to access the page. Do not put it in client-side browser code or public logs. - Inspect status and content type. Record the status code, response headers, and a small sample of the body. An error document rendered inside an image element can look like a blank image. Expect an image response for a screenshot download.
- Handle the response as bytes. Do not parse an image body as JSON or text. When returning it from your own server, preserve the image bytes and set the response content type to the actual image type.
- Check the image URL separately. For
page_screenshot_image, confirm your webhook payload includes the field and that your server can fetch the URL. Avoid accidentally encoding, truncating, or escaping the URL when storing or forwarding it. - Check browser restrictions. If a browser frontend calls the API directly, inspect the browser console and network panel for blocked requests, mixed-content issues, or authentication failures. A server-side request can help distinguish browser policy from a bad stored screenshot.
- Inspect dimensions and rendering. Confirm the downloaded file has nonzero length and valid image dimensions, then display that local file. If it opens locally but not in your app, focus on the app’s image URL, response headers, and rendering code.
PageCrawl lets webhook payload fields be configured. The webhook guide lists page_screenshot_image among the image fields. If your handler depends on it, make sure it is selected in the webhook configuration. The guide also describes a test delivery for checking the connection: PageCrawl webhook integration.
5. Verify the fix with a new check
- Save the one targeted setting you changed.
- Trigger a new check and note its check ID.
- Open the screenshot for that exact check in PageCrawl.
- Fetch that check’s screenshot using its Developer mode request.
- Compare the stored image, downloaded file, and application display.
- If the image is still blank, inspect the new status and error before changing another setting.
Keep a known-good image and check ID during diagnosis. That makes it easier to tell whether a code or configuration change fixed capture, retrieval, or rendering.
6. Troubleshooting common errors
| Problem | Likely cause | Fix |
|---|---|---|
| 401 response from the API | Missing, invalid, or expired Bearer token | Send the token in the authorization header and check that it belongs to the account and workspace that owns the page. |
| 403 response | The API request or target page is forbidden | Distinguish an API authorization error from a captured target-site 403. Check the request token and inspect the stored screenshot and check error. |
| 404 response | Incorrect page/check ID, unsupported route, or missing target page | Copy the exact request in Developer mode. Do not infer that every endpoint accepts a special value such as latest; use only the value documented for that route. |
| Downloaded file contains JSON or HTML | The response is an API error or other non-image response | Check status and content type before saving it as an image. Read the error response and correct the route, IDs, or authorization. |
| Image URL field is missing from webhook | The selected webhook payload fields omit screenshot data | Include page_screenshot_image in the webhook fields, then use a test delivery to verify the payload. |
| Image works locally but is blank in a webpage | Incorrect URL, browser restriction, bad response headers, or incorrect frontend handling | Inspect the request in the browser network panel. Serve valid image bytes with an image content type and verify the URL is reachable from the browser. |
| Timeout or blank page after a wait change | The page still did not become ready, or the check reached its overall time limit | Use a meaningful readiness condition, remove unnecessary delays, and check the plan timeout and captured error. |
| Selector not found | The page changed or the selector is evaluated before the element appears | Recheck the selector in the current page and add the appropriate wait or interaction before extraction. |
| Content is missing only below the fold | Lazy-loaded content did not load before capture | Use the documented scroll-to-bottom action and a bounded wait, then inspect the new screenshot. |
7. Performance, reliability, and cost considerations
- Keep waits purposeful. A fixed delay adds time to every check and still cannot guarantee readiness. Prefer waiting for the content your monitor needs, and keep scripts within PageCrawl’s documented 30-second JavaScript safety timeout.
- Respect the check timeout. The documented limits are 45 seconds for Free, 90 seconds for Standard, and 180 seconds for Enterprise and Ultimate. Increasing a wait is useful only if the check has enough remaining time and the page can actually finish loading.
- Change one variable per rerun. Changing engine, location, JavaScript, and actions together makes it difficult to identify what fixed the capture.
- Make webhook handling resilient. PageCrawl documents automatic retries when webhook delivery fails temporarily. Return a 2xx response after accepting the payload; process heavier work asynchronously so your handler can respond promptly. See the API and webhooks guide.
- Control API polling. The PageCrawl API developer guide documents rate limits of 60 requests per minute on Free and 300 per minute on paid plans. Avoid tight retry loops; back off after HTTP 429.
- Check plan-specific limits before raising timeouts or enabling a feature. Use PageCrawl’s current plan and configuration screens for the limits that apply to your account. Do not assume a longer timeout resolves authentication, bot protection, or a page that never renders.
Or skip the browser setup
If the task is to capture a page as an image, ScreenshotNeo offers a website screenshot API and MCP server. One GET request takes a URL and returns a screenshot. See the ScreenshotNeo website and 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
Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Sign up for free and get 1,000 screenshots a month with no card.
FAQ
Does a successful screenshot URL prove the page rendered?
No. Open the corresponding stored image and confirm that it contains the expected page. A returned URL alone does not establish that the capture is useful.
Can I use a PageCrawl screenshot endpoint to create a new live screenshot?
The documented route retrieves a screenshot associated with a monitored page check. PageCrawl describes it as part of its monitoring API. Use its API reference to confirm the available routes and behavior.
Should I add waitFor or delay to the screenshot request?
Only if PageCrawl documents that parameter for the endpoint you are using. Screenshot API parameters differ between products. Configure PageCrawl’s documented page adjustments or actions instead of copying another vendor’s query parameters.
Does changing the capture location fix a login or CAPTCHA?
No guarantee. A location can help diagnose region-specific behavior, but it does not provide login credentials and does not ensure that a bot challenge will be cleared.


