URL2PNG Returns a Blank Screenshot: Causes and Fixes
Diagnose a blank URL2PNG screenshot by checking the signed request, cache, page readiness, and capture area in a controlled sequence.
A blank URL2PNG screenshot can come from a malformed or incorrectly signed request, a cached result, a page captured before its content appears, or a capture area that misses the content. URL2PNG’s official documentation does not identify one universal cause. Check the actual response first, then change one variable at a time: freshness, readiness, viewport, and capture mode.
This guide follows URL2PNG’s documented v6 request and capture options. The primary reference is its official quickstart documentation; its product page describes the service as a website screenshot API.
1. Confirm the response is really a blank image
Before changing rendering settings, determine whether URL2PNG returned an image and whether your application is displaying that image correctly. A failed API request, an error response saved with an image extension, and a valid image whose pixels are blank are different problems.
- Inspect the HTTP status, response headers, and body from the API call.
- Open the response body as an image independently of your application. Check its dimensions and whether it contains pixels of the expected kind.
- Confirm the target URL is encoded in the request and that the request includes the required API key and token.
- Keep API secrets out of public logs, screenshots, and bug reports. Redact them before sharing a request.
URL2PNG v6 uses a token computed from the entire query string and the secret key. If you add or change an option, regenerate the token for the resulting complete query string; a token for a different set of parameters does not validate the request. See the URL2PNG quickstart for its exact signing procedure and parameter format.
2. Check the signed URL and query parameters
Construct the request according to URL2PNG’s v6 documentation, including its API key, target URL, options, and matching token. Encode the target URL as a query parameter. Do not copy a token from a request and then edit the options: the signature must correspond to the full query string.
The following is a request-shape example, not a substitute for URL2PNG’s signing instructions. URL2PNG documents an MD5 token derived from the complete query string and secret; use its quickstart to generate the exact token required for your parameters.
curl -G 'https://api.url2png.com/v6/P4-APIKEY/GENERATED_TOKEN/png/' \
--data-urlencode 'url=https://example.com/' \
--data-urlencode 'viewport=1480x1037' \
-o screenshot.png
Replace the host/path and credentials with the endpoint and values from the current official documentation. Do not treat the placeholder token above as valid. The documented default viewport is 1480×1037; the example makes that setting visible so you can compare it with your actual request.
For an integration, log the non-secret request options and response status, but redact the API key, secret, and token. If your application builds the signed URL, inspect the final encoded query string and verify that the token was generated after every option was finalized.
3. Force a fresh capture to rule out stale cache
URL2PNG documents a default TTL of 2,592,000 seconds (30 days). If the blank result may be old, request a fresh screenshot by setting a new value for the documented unique parameter. Compare that output with the original.
curl -G 'https://api.url2png.com/v6/P4-APIKEY/GENERATED_TOKEN/png/' \
--data-urlencode 'url=https://example.com/' \
--data-urlencode 'unique=blank-check-20261004-01' \
-o fresh-screenshot.png
The token must be regenerated to match the full query string, including unique. Use a different value for each freshness check. This is a cache-busting diagnostic, not proof that caching caused the blank image; if the new capture is still blank, continue to readiness and capture-area checks.
4. Give the page time to render
A page can be visually empty at the moment the screenshot is taken even when its request succeeds. URL2PNG provides delay, which waits a fixed number of seconds after document readiness and asset loading. Its docs describe this as generally useful for animations. Use a short, controlled delay to test whether timing matters.
curl -G 'https://api.url2png.com/v6/P4-APIKEY/GENERATED_TOKEN/png/' \
--data-urlencode 'url=https://example.com/' \
--data-urlencode 'delay=3' \
-o delayed-screenshot.png
For a page you control, URL2PNG also documents say_cheese=true: capture waits until the page contains <div id="url2png-cheese"></div>. Add that marker only after the content you need is ready. This is more targeted than choosing an arbitrary long delay when your application can signal readiness.
<!-- Render this only after the screenshot-ready content is present. -->
<div id="url2png-cheese"></div>
Follow the official documentation for the exact say_cheese request syntax and token generation. Avoid increasing delays without limit: longer waits can increase capture latency, and they do not fix content hidden by a failed script, access restriction, or incorrect viewport.
5. Check viewport dimensions and full-page mode
The documented default viewport is 1480×1037, and viewport capture is not the same as capturing the entire document. Verify that the desired content falls inside the viewport and that the page layout is not responsive in a way that hides it at that size.
- Viewport capture: use when the content should be visible in the initial browser window. Set a viewport appropriate to the page’s responsive breakpoints.
- Full-page capture: set
fullpage=truewhen content extends below the initial viewport. URL2PNG describes this as an attempt to capture the whole document canvas.
curl -G 'https://api.url2png.com/v6/P4-APIKEY/GENERATED_TOKEN/png/' \
--data-urlencode 'url=https://example.com/' \
--data-urlencode 'fullpage=true' \
-o full-page.png
Regenerate the token whenever you change fullpage or the viewport. If a page is blank only at one viewport, inspect its responsive CSS and verify the actual content region rather than assuming the API returned a bad image.
6. Reproduce with one variable at a time
Use a controlled sequence to find which condition changes the result. Start with the same target URL and a known simple public page, then vary one setting per request.
- Capture a simple public page with the documented request format.
- Capture the target URL with the same baseline settings.
- Repeat the target request with a new
uniquevalue to test freshness. - Add a short
delay, or use the documented DOM marker if you control the page. - Set a viewport that includes the content, then separately test
fullpage=true. - If the page behaves differently by browser identity or language, test URL2PNG’s documented user-agent or Accept-Language overrides individually.
If the simple page works and the target does not, investigate target-specific behavior such as its rendering timing, responsive layout, or requirements for headers. Bot blocking, authentication, and other access restrictions are possible things to investigate, but the reviewed URL2PNG documentation does not identify them as established causes of blank screenshots. Confirm them from the target page and response rather than assuming.
7. Troubleshooting symptoms
| Symptom | What to check | Next step |
|---|---|---|
| The request fails or returns something other than an image | HTTP status, response body, endpoint, API key, token, and URL encoding | Follow the v6 quickstart and recompute the token from the complete query string and secret. |
| The output is an older blank image | Whether the request may be using the documented 30-day default TTL | Set a new unique value, regenerate the signature, and compare. |
| The page background appears but content is missing | Whether content appears after the capture is ready | Test a short delay; for a page you control, use the documented say_cheese marker. |
| Some content is missing near the edges or below the fold | Viewport size and whether the capture is viewport-only | Choose a suitable viewport; test fullpage=true for document content below the fold. |
| A simple page works but the target is blank | Target-specific timing, layout, language, user-agent, or access requirements | Compare one documented override at a time and inspect the target’s behavior. Treat bot checks or authentication as hypotheses until confirmed. |
| The downloaded file is not a usable screenshot | Whether the application saved an API error body as an image or mishandled the response | Check status and content type before saving or displaying the body as an image. |
8. Reliability, latency, and cost considerations
For reliable diagnosis, preserve the exact non-secret parameter set for each attempt, record the response status, and change one option at a time. Keep a known-good public page as a control. A successful control narrows the problem to the target or its specific settings; it does not identify the cause on its own.
Use unique for a deliberate freshness check rather than changing many request parameters at once. Use the shortest delay that establishes whether readiness is the issue, because waiting longer adds latency. Full-page capture may produce a larger image than viewport capture, so use it when the content you need extends beyond the viewport.
URL2PNG’s plans page describes screenshot quotas and monthly plan prices, and says screenshots are cached for 30 days. Those terms can change; check the current URL2PNG plans page before estimating ongoing usage. Do not assume every blank result is billed or free unless the provider’s current terms say so.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. It can return PNG, JPEG, WebP, or PDF from one GET request, with options for full-page capture, selectors, waits, custom headers, cookies, user agents, and more. See the ScreenshotNeo API documentation for the complete parameter list.
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}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);
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 step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server gives AI agents tools for screenshots, page information, and PDF capture. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots.
Create a free ScreenshotNeo account for 1,000 screenshots a month with no card.
FAQ
Does a blank screenshot prove URL2PNG is down?
No. A blank result alone does not establish a service outage. Check the response, signature, cache, readiness, and capture area, and compare with a simple public page.
Is the default cache TTL one day?
No. The reviewed URL2PNG quickstart documents a default TTL of 2,592,000 seconds, or 30 days.
Should I always use full-page capture?
No. Use it when the required content extends below the viewport. For an above-the-fold capture, set an appropriate viewport and keep the capture area limited to what you need.
Can I add arbitrary options without changing the token?
No. URL2PNG’s v6 token depends on the complete query string and secret. Generate a matching token after finalizing the options.


