CaptureKit Screenshots Show a Blank Page: Troubleshooting Guide
Diagnose a blank CaptureKit screenshot by checking the response, authentication, timing, capture settings, resource filters, and target page behavior.
A blank CaptureKit screenshot has no documented universal cause. First determine whether the API returned an error or a successful image with no visible content. Then check the target URL, API key and account status, capture timing, selector and viewport settings, resource-blocking options, and what the target page serves to the capture environment. Change one variable at a time so each result narrows the cause.
1. Inspect the response before changing capture settings
Record the HTTP status, response body, and whether the response is actually an image. A blank-looking result can be an API or account error, or it can be a successful capture of a page that was empty in the rendering environment. CaptureKit’s API reference lists request and account errors; its quick start says API Logs include status, duration, and credit cost. See the CaptureKit API reference and quick start.
- Inspect the HTTP status and content type. Do not assume every response body is a PNG or JPEG.
- Check the CaptureKit API Logs entry for status, duration, and credit cost.
- If the response is an error, resolve that error before adjusting browser rendering options.
- If the request succeeded, save the exact image response and inspect it at its original size.
CaptureKit documents different handling for inactive or expired keys, rate limits, payment-required responses, forbidden responses, and internal errors. Follow the observed status: activate or replace the key, back off before retrying a rate limit, resolve billing, check permissions, or retry/contact support for an internal error. Do not label an account error a rendering bug.
2. Verify the key, URL, and request
The screenshot endpoint requires a target URL and an API key in the x-api-key header. Confirm the URL is the intended public page, including its scheme and path. Use CaptureKit’s /v1/usage endpoint with the same key to check authentication independently of screenshot rendering. Keep the key on a backend; do not expose it in browser or mobile code.
curl -i "https://api.capturekit.dev/v1/usage" \
-H "x-api-key: $CAPTUREKIT_API_KEY"
Use the host and exact endpoint shown in your CaptureKit account or current documentation if they differ. A successful usage request narrows the issue to the capture request or target page; it does not prove the target will render successfully.
3. Run a minimal screenshot request
Start with the fewest parameters: a reachable public URL, valid key, and default viewport. The API reference documents the screenshot endpoint and its parameters. The following examples show the request shape; use the endpoint URL and required query or body fields specified in your CaptureKit account documentation.
cURL
curl -i -G "https://api.capturekit.dev/v1/screenshot" \
-H "x-api-key: $CAPTUREKIT_API_KEY" \
--data-urlencode "url=https://example.com" \
-o capture-response
Inspect the response headers before treating capture-response as an image. Replace the illustrative host/path with the endpoint shown in the current CaptureKit API reference.
Python
import os
import requests
endpoint = "https://api.capturekit.dev/v1/screenshot" # Use your documented endpoint
response = requests.get(
endpoint,
headers={"x-api-key": os.environ["CAPTUREKIT_API_KEY"]},
params={"url": "https://example.com"},
timeout=90,
)
print(response.status_code, response.headers.get("content-type"))
response.raise_for_status()
with open("capture-response", "wb") as image_file:
image_file.write(response.content)
Node.js
const endpoint = 'https://api.capturekit.dev/v1/screenshot'; // Use your documented endpoint
const params = new URLSearchParams({ url: 'https://example.com' });
const response = await fetch(`${endpoint}?${params}`, {
headers: { 'x-api-key': process.env.CAPTUREKIT_API_KEY },
signal: AbortSignal.timeout(90_000),
});
console.log(response.status, response.headers.get('content-type'));
if (!response.ok) throw new Error(`CaptureKit returned ${response.status}`);
const bytes = new Uint8Array(await response.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('capture-response', bytes));
These samples deliberately omit undocumented response-format and option names beyond those listed in the research reference. Consult the CaptureKit API reference for the current endpoint URL and exact parameter placement before running them.
4. Wait for the target page to become renderable
A successful request can still capture an empty viewport if the site draws its content after the initial document response. CaptureKit provides separate controls for capture timing: wait_until, delay, and wait_for_selector. Its documented wait_until choices are domcontentloaded, load, networkidle0, and networkidle2; delay is documented from 0 to 10 seconds.
- Try a later lifecycle condition if the page needs scripts or assets to finish loading.
- Try a short delay when content appears after load, such as after a client-side request.
- Prefer
wait_for_selectorwhen a stable element identifies readiness, such as the main content container. - Do not wait for a selector that is absent for logged-out, consent, or error states.
- Network-idle conditions may be unsuitable for pages with persistent network activity; test them against the page’s behavior.
There is no universal best wait condition or delay. Use one change at a time and keep the shortest condition that reliably captures the required content. CaptureKit’s rendering guidance also calls out JavaScript execution and lazy-loaded images when assessing completeness: CaptureKit rendering guidance.
5. Confirm which part of the page is captured
CaptureKit documents a default viewport of 1280 × 1024 and full_page=false. A viewport capture can look empty when the relevant content is below the fold, outside the chosen viewport, or hidden at a responsive breakpoint.
- Compare the default viewport with the width and height at which the page is expected to show content.
- Check any device-emulation setting and ensure it matches the target layout you intend to inspect.
- Set
full_page=truewhen you need the document beyond the initial viewport. - For pages that add content only when scrolled, also evaluate
full_page_scroll=trueandfull_page_scroll_duration. The documented duration default is 400 ms.
Full-page capture and scrolling to trigger lazy elements are separate options. Turning on full-page capture alone does not mean the page was scrolled to load every lazy section. Confirm the exact parameter names and allowed values in the API reference.
6. Temporarily remove resource and selector filters
CaptureKit can block resource types and URL patterns. Its documented resource types include scripts, stylesheets, images, XHR, and fetch. Blocking scripts can prevent client-rendered content from appearing; blocking stylesheets can make content difficult to see; blocking images can leave image-only regions blank; and blocking XHR or fetch can prevent data-driven sections from populating.
For diagnosis, remove or disable block_resources, block_urls, remove_selectors, and ad-removal settings. Compare the result, then restore only the intentional filters individually. This makes it possible to identify whether a filter caused the empty or incomplete output.
Also check selector, which controls what element is captured. Verify that the selector matches an element present in the rendered DOM and is not paired with a wait condition that can never complete. For a first comparison, capture the default page area with no selector.
7. Check what the target serves to the capture environment
A capture service may receive a different page state than your local browser. The URL could redirect to sign-in, a bot check, a region-dependent page, or an empty state. Confirm the final destination and whether the content is available without an interactive session. If only one viewport fails, test the intended dimensions and a supported device setting.
The CaptureKit endpoint includes a proxy option, but the documentation does not promise that using it will solve any particular target restriction. Treat it as a variable to evaluate only when your setup and account support it; do not assume it bypasses access controls or guarantees the same response as a human browser.
8. Troubleshooting table
| Symptom | Likely area to inspect | Next check |
|---|---|---|
| HTTP error instead of image | Authentication, account, request, or service status | Read status/body; verify the key with /v1/usage; inspect API Logs. |
| Valid image file, entirely white | Target state or render timing | Open the target directly, then try a readiness selector or suitable wait condition. |
| Header or shell appears, body is empty | Client-side content, data request, or blocked scripts | Remove resource and URL blocks; wait for a main-content selector. |
| Top portion appears, expected content does not | Viewport, full-page, or lazy loading | Check viewport dimensions, full_page, and separately full_page_scroll. |
| Capture waits too long or fails waiting | Unsuitable network-idle condition or absent selector | Choose a selector that exists for the current state, or try another documented wait condition. |
| Only one screen size is blank | Responsive layout or device emulation | Compare the intended width/height with the default 1280 × 1024 viewport. |
| Blank only for a particular URL | Redirect, sign-in, bot check, region, or page-specific behavior | Check the final URL and public availability from the capture environment. |
9. Reliability, performance, and cost considerations
There is no documented single fix or published success-rate figure for blank captures. Keep the original request and its response metadata, then change one setting per attempt. This creates a useful diagnostic record and avoids attributing the result to several simultaneous changes.
Longer delays and broad network-idle waits can increase capture time; full-page scrolling can require additional rendering work. Use only the wait and page extent the task needs. For recurring captures, distinguish API errors from successful captures of an empty target state in your logs, and retry only errors that are plausibly transient. Follow CaptureKit’s documented backoff guidance for rate limits; do not retry invalid keys or unresolved billing errors as if they were transient rendering problems.
CaptureKit’s materials reviewed here do not establish a universal cost impact for each retry or setting. Check the account’s current billing and log details rather than assuming that an empty image was free or billed.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF; its API documentation lists 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
With ScreenshotNeo, cookie banners are accepted like a visitor and removed along with known consent platforms, newsletter popups, and chat widgets before the shot; those steps can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are never billed, and response headers identify the page verdict and billing status. An MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Sign up for ScreenshotNeo and get 1,000 free screenshots a month with no card.
FAQ
Is a blank screenshot proof that CaptureKit is down?
No. Check the response status and API Logs first; the blank result can come from request/account handling or from the target page state.
Should I always use the longest delay?
No. Use the shortest wait condition that allows the needed content to appear. A longer wait adds time and cannot fix a missing selector, blocked resource, or inaccessible page.
Will full-page mode load every lazy image?
Not by itself. CaptureKit documents full-page capture and scrolling to load lazy elements as separate controls.
Can I put my API key in frontend code?
CaptureKit advises keeping API keys on a backend rather than exposing them in browser or mobile code.


