URL2PNG API Authentication Error: How to Fix It
Fix URL2PNG v6 authentication errors by checking your account credentials, signing the exact encoded query string, and verifying permissions.
For URL2PNG v6, an authentication error usually means the API key, secret, token, or signed query string does not match what the request sends. Confirm that the key and secret belong to the intended account, URL-encode the request parameters once, calculate the MD5 token from the complete encoded query string followed directly by the secret, and send that same query string unchanged.
URL2PNG’s official quickstart guide describes the token as the MD5 hash of the entire query string plus the secret key, and says to generate a token for each unique request. The examples below show the v6 signing flow. Check the current guide for endpoint syntax before deploying: the documentation includes legacy material as well as v6 examples.
1. Check the key, secret, and account
- Use the API key and secret from the same URL2PNG account. The official quickstart says the assigned API key begins with
P; the secret is a separate value. - Check that your application is using the intended credentials in the environment where the request fails. Avoid accidentally mixing development and production settings.
- If the call comes through an integration and returns HTTP 401, check that integration’s saved credentials and the URL2PNG portal permission settings. The D3 integration guide specifically advises checking portal permissions for a 401; this is integration guidance, not a complete URL2PNG error-code specification.
HTTP 401 generally indicates that the request lacks valid authentication credentials for the resource. It does not, by itself, identify which URL2PNG signing input is wrong. See MDN’s HTTP 401 reference for the general status meaning.
2. Sign the exact query string you send
The signing input is the complete query string, followed immediately by the secret. The digest is MD5, represented as lowercase hexadecimal. Build the encoded query string once and reuse that exact string in both the hash input and request URL.
- Choose all query parameters for the capture, including the target URL and any options.
- Encode their names and values consistently to make the query string.
- Append the secret directly to the complete query string; do not insert a separator unless the current URL2PNG documentation specifies one.
- Calculate the MD5 digest of that combined byte string.
- Put the API key and token in the path, then send the query string used to calculate the token.
A common failure is to hash a value that differs from the transmitted query string: for example, hashing an unescaped target URL but sending an encoded one, omitting an option from the hash, or changing parameter serialization after signing. The need for an exact match follows from URL2PNG’s documented formula and examples.
3. Runnable Python example
This example constructs the query string once with Python’s standard URL-encoding library, signs it, and sends it. Replace the placeholders with credentials from your account. The route format follows the v6 form shown in the URL2PNG quickstart; compare it with the current official sample for your account and endpoint.
import hashlib
import os
from urllib.parse import urlencode
import requests
api_key = os.environ["URL2PNG_API_KEY"]
secret = os.environ["URL2PNG_SECRET"]
# Include the capture options your integration needs. Add or remove options
# according to the current URL2PNG v6 documentation.
params = {
"url": "https://example.com/",
"fullpage": "true",
}
# Build this once. The same encoded string is hashed and transmitted.
query_string = urlencode(params)
token_input = (query_string + secret).encode("utf-8")
token = hashlib.md5(token_input).hexdigest()
request_url = f"https://www.url2png.com/v6/{api_key}/{token}/png/?{query_string}"
response = requests.get(request_url, timeout=90)
if response.status_code == 401:
raise RuntimeError(
f"URL2PNG returned HTTP 401. Check credentials, signed query string, "
f"and account permissions. Response: {response.text[:1000]}"
)
response.raise_for_status()
with open("capture.png", "wb") as image_file:
image_file.write(response.content)
print(f"Saved capture.png ({len(response.content)} bytes)")
Set credentials without putting them in source control. For example, in a shell set URL2PNG_API_KEY and URL2PNG_SECRET in your environment before running the script. Do not print the token input: it contains the secret.
4. Verify the request shape and encoding
The quickstart shows the key and token in the URL path and the capture parameters in the query string. It documents a v6 path of the form /v6/{apikey}/{token}/png/?{query_string} and also includes a shell example using a service-root form. Follow the current official sample for the endpoint and language you use; do not transplant an older v3 example into a v6 request.
- Check path components: confirm the API version, key, token, and output route are in the documented positions.
- Check the query: the target URL and all other parameters used for the capture should be represented in the string you signed.
- Check encoding: use one consistent encoder and do not encode the URL differently between signing and transmission.
- Check serialization: parameter ordering and escaping can change the resulting string. Generate the final string once rather than rebuilding it separately for hashing and sending.
- Check token freshness: URL2PNG says to generate a token for each unique request. Recalculate it whenever the query changes.
5. cURL example
cURL does not calculate URL2PNG’s MD5 token automatically. Generate the token in application code using the exact encoded query string, then make the request. This shell example assumes you already have the token for the exact query shown; it keeps the endpoint anatomy visible without pretending cURL has signed the request.
export URL2PNG_API_KEY='YOUR_API_KEY'
export URL2PNG_TOKEN='TOKEN_FOR_THIS_EXACT_QUERY'
curl --fail-with-body --get \
"https://www.url2png.com/v6/${URL2PNG_API_KEY}/${URL2PNG_TOKEN}/png/" \
--data-urlencode 'url=https://example.com/' \
--data-urlencode 'fullpage=true' \
--output capture.png
For this request, calculate the token from the encoded query string that the request actually uses, followed by the secret. If your cURL version lacks --fail-with-body, remove that option and inspect the status and response body separately. Avoid enabling verbose output in shared logs if it could expose credentials.
6. Common errors and fixes
| Symptom | Likely cause | What to do |
|---|---|---|
| HTTP 401 after changing the target URL | The token was generated for the previous query. | Rebuild the complete encoded query string and recalculate the token for this request. |
| HTTP 401 despite a newly generated token | The key and secret may be from different accounts, or the transmitted query differs from the signed one. | Verify the credential pair, then compare the exact query string used as hash input with the transmitted query. |
| Only URLs with special characters fail | Reserved characters, spaces, or nested URL query parameters may be encoded inconsistently. | Use a standard URL encoder once. Sign the resulting string and send that same string. |
| Requests from an integration fail but local calls work | The integration may have stale or incorrect credentials, or account permissions may be missing. | Update the integration’s saved credentials and check URL2PNG portal permissions. D3’s integration documentation recommends the permission check for its 401 case. |
| Token works for one option set but not another | A parameter was added, removed, or changed without recalculating the token. | Generate a new token for every unique query string. |
| Failure began after copying an old sample | The sample may use a legacy API version or a different URL form. | Use the current v6 quickstart for the request language and endpoint you are implementing. |
| Response is not 401, or the body gives a different error | The issue may not be authentication, or URL2PNG may return additional diagnostic details. | Record the status and response body, then diagnose that specific response. The reviewed URL2PNG pages do not define a complete authentication error table. |
7. Troubleshooting checklist
- [ ] The API key and secret belong to the same intended account.
- [ ] The token is freshly generated for this request’s parameters.
- [ ] The query string was encoded once and reused for signing and transmission.
- [ ] The hash input is the complete query string immediately followed by the secret.
- [ ] The digest is MD5 and rendered as lowercase hexadecimal.
- [ ] The API version and route match the current v6 example.
- [ ] Integration permissions and saved credentials are current.
- [ ] You captured the exact status and response body for any remaining failure.
8. Reliability, performance, and cost considerations
Authentication failures are best debugged with a redacted record of the request path shape, parameter names, status, and response body. Never log the secret or publish a full credential-bearing URL. To make signing reliable, keep query construction and token generation in one function so a later option change cannot silently leave a stale token.
URL2PNG’s cited quickstart explains request signing but does not establish latency, uptime, retry behavior, or pricing. Do not assume a 401 is transient: first correct the credentials or signing input. If the response remains unclear, preserve the status, body, and a redacted request URL and contact URL2PNG support at the address listed on its legal page (support@url2png.com). Never include an unredacted secret in a support ticket.
Or skip the browser setup
If the goal is simply to get a website screenshot, ScreenshotNeo provides a screenshot API and MCP server. Its one-call API avoids implementing browser capture and URL2PNG-style request signing:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for the request options. 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.
Sign up free for 1,000 screenshots a month, with no card required.
FAQ
Does a URL2PNG token stay valid for every request?
The quickstart says to generate a token for each unique request. Recalculate it when the query string changes.
Can I use SHA-256 instead of MD5?
The URL2PNG v6 quickstart specifies MD5 for this token recipe. Follow the provider’s current documented algorithm.
What should I send URL2PNG support?
Send the HTTP status, response body, and a redacted request URL. Remove the secret and any credentials before sharing logs or a ticket.


