ScreenshotNeo

BlogHow-to

ScreenshotMachine API Authentication: How to Fix an Invalid Access Key

Fix ScreenshotMachine’s invalid access key error by checking the response code, request parameters, and secret phrase hash. Learn when to contact support.

By the ScreenshotNeo team4 October 20268 min read

To fix a ScreenshotMachine invalid_key error, first read the X-Screenshotmachine-Response header, then confirm that your GET request sends your account’s customer key in the key parameter to https://api.screenshotmachine.com/. If the code is invalid_hash, check the secret phrase and hash instead. These are separate errors with separate fixes.

This guide covers the documented authentication errors, runnable requests, secret phrase hashing, and what to do when the key still fails. ScreenshotMachine’s public documentation cannot verify an individual account’s key status.

1. Read the API’s error code

ScreenshotMachine documents API error codes in the X-Screenshotmachine-Response response header. Inspect that header before changing credentials. The API may also return an error image containing text, but the header is the explicit code-bearing signal documented by ScreenshotMachine.

Response code Meaning Next step
invalid_key The specified customer key is invalid. Check that you copied the intended account’s customer key and sent it as key.
missing_key The request did not include a customer key. Add the key query parameter. Check for a misspelled or empty parameter.
invalid_hash The supplied hash is invalid. If the account has a secret phrase, recompute the hash from the exact URL parameter value and phrase.
no_credits The account has exhausted its credits. Check account credits. This is not an invalid-key error.
invalid_url The URL is invalid, or the target requires authorization. Check the target URL and whether the page is publicly accessible.

These distinctions come from the ScreenshotMachine API documentation.

2. Confirm the endpoint and parameter names

ScreenshotMachine’s website screenshot endpoint accepts an HTTP GET request. Pass the customer key as key and the target page as url:

https://api.screenshotmachine.com/?key=YOUR_CUSTOMER_KEY&url=https%3A%2F%2Fexample.com

Use your actual customer key from the account. Do not substitute an unrelated token or send the credential under a different parameter name. URL-encode the target page when constructing the query string; the examples below handle encoding for you.

cURL

curl -sS -D response-headers.txt -G "https://api.screenshotmachine.com/" \
  --data-urlencode "key=YOUR_CUSTOMER_KEY" \
  --data-urlencode "url=https://example.com" \
  -o screenshot.png

# Inspect the documented error header, if present:
rg -i '^X-Screenshotmachine-Response:' response-headers.txt

The output file may be an error image if the request failed. Check the response header rather than assuming that any downloaded image is a successful screenshot.

Python

import requests

endpoint = "https://api.screenshotmachine.com/"
params = {
    "key": "YOUR_CUSTOMER_KEY",
    "url": "https://example.com",
}

response = requests.get(endpoint, params=params, timeout=90)
code = response.headers.get("X-Screenshotmachine-Response")
if code:
    print("ScreenshotMachine response:", code)
else:
    print("No X-Screenshotmachine-Response error code was returned")

response.raise_for_status()
with open("screenshot.png", "wb") as output:
    output.write(response.content)

Install the dependency with python -m pip install requests. Keep the key out of source control; load it from an environment variable or a secrets manager in an application.

Node.js

const endpoint = new URL("https://api.screenshotmachine.com/");
endpoint.searchParams.set("key", process.env.SCREENSHOTMACHINE_KEY ?? "YOUR_CUSTOMER_KEY");
endpoint.searchParams.set("url", "https://example.com");

const response = await fetch(endpoint);
const code = response.headers.get("X-Screenshotmachine-Response");
if (code) console.log("ScreenshotMachine response:", code);
if (!response.ok) throw new Error(`HTTP ${response.status}`);

const bytes = Buffer.from(await response.arrayBuffer());
await import("node:fs/promises").then(fs => fs.writeFile("screenshot.png", bytes));

This uses the built-in fetch available in current Node.js releases. Set SCREENSHOTMACHINE_KEY in the process environment before running the script.

3. Fix a missing or invalid customer key

  1. Open the account that owns the API integration and locate its customer key.
  2. Copy the key again, checking for leading or trailing whitespace, truncation, and accidental quote characters.
  3. Confirm the request sends it as key, with a non-empty value, to the official API endpoint.
  4. Retry and inspect X-Screenshotmachine-Response again.
  5. If the copied account key still returns invalid_key, check the account or contact ScreenshotMachine support. The public API documentation cannot establish whether a specific key is active, changed, or otherwise valid for your account.

A missing_key response points to request construction or configuration: the service did not receive the key. An invalid_key response means a key was specified but the service considers it invalid. Avoid logging the key while debugging; log whether it is present and the returned error code instead.

4. Fix an invalid hash when a secret phrase is configured

If a secret phrase is set in account settings, ScreenshotMachine requires a hash. Its documented hash is the MD5 digest of the URL parameter value concatenated directly with the secret phrase:

hash = MD5(url_parameter_value + secret_phrase)

Use the exact URL value that the request sends. Differences in scheme, path, query parameters, escaping, or a trailing slash can produce a different digest. Concatenate the strings without adding a separator unless the value itself contains one. If no secret phrase is configured, the official examples leave the phrase empty and omit hash.

cURL with a precomputed hash

curl -sS -D response-headers.txt -G "https://api.screenshotmachine.com/" \
  --data-urlencode "key=YOUR_CUSTOMER_KEY" \
  --data-urlencode "url=https://example.com" \
  --data-urlencode "hash=YOUR_PRECOMPUTED_MD5_HASH" \
  -o screenshot.png

Compute the digest in your application or a trusted local environment. Do not put the secret phrase directly into a shared shell history or a command that may be visible in process listings.

Python hash and request

import hashlib
import os
import requests

url_value = "https://example.com"
secret_phrase = os.environ["SCREENSHOTMACHINE_SECRET_PHRASE"]
digest = hashlib.md5((url_value + secret_phrase).encode("utf-8")).hexdigest()

response = requests.get(
    "https://api.screenshotmachine.com/",
    params={
        "key": os.environ["SCREENSHOTMACHINE_KEY"],
        "url": url_value,
        "hash": digest,
    },
    timeout=90,
)
print("ScreenshotMachine response:", response.headers.get("X-Screenshotmachine-Response"))
response.raise_for_status()
with open("screenshot.png", "wb") as output:
    output.write(response.content)

MD5 here is the specific digest required by the documented API signing scheme; it is not a recommendation for storing passwords or designing a new security protocol.

Node.js hash and request

import { createHash } from "node:crypto";
import { writeFile } from "node:fs/promises";

const urlValue = "https://example.com";
const secretPhrase = process.env.SCREENSHOTMACHINE_SECRET_PHRASE;
if (!secretPhrase) throw new Error("Set SCREENSHOTMACHINE_SECRET_PHRASE");
const hash = createHash("md5").update(urlValue + secretPhrase, "utf8").digest("hex");

const endpoint = new URL("https://api.screenshotmachine.com/");
endpoint.searchParams.set("key", process.env.SCREENSHOTMACHINE_KEY);
endpoint.searchParams.set("url", urlValue);
endpoint.searchParams.set("hash", hash);
const response = await fetch(endpoint);
console.log("ScreenshotMachine response:", response.headers.get("X-Screenshotmachine-Response"));
if (!response.ok) throw new Error(`HTTP ${response.status}`);
await writeFile("screenshot.png", Buffer.from(await response.arrayBuffer()));

5. Troubleshoot common failures

Symptom Likely cause Fix
missing_key The key parameter is absent, empty, misspelled, or not included in the final request. Inspect the constructed URL without exposing its credential; confirm the parameter name is exactly key and the value is present.
invalid_key The supplied customer key is not valid for the API. Copy it from the intended account again. If it continues, verify account status or contact support.
invalid_hash The account uses a secret phrase but the request’s hash is absent, incorrect, or based on a different URL value. Recompute MD5 from the exact URL parameter value followed by the exact secret phrase. Do not add a separator.
no_credits The account’s credits are exhausted. Check the account’s credits. Changing the key or hash does not address this response.
invalid_url The target URL is malformed or the destination requires authorization. Check URL encoding, spelling, reachability, and whether the page can be accessed by the screenshot service.
No visible code; downloaded file contains an error The response may contain an error image, or the header was not saved or inspected. Capture response headers with your HTTP client and read the image or response body for context.
Works locally but fails in deployment The deployed process may have a missing or stale key or secret phrase. Check deployment secret configuration and the runtime environment. Do not print credential values to logs.

If the API returns an HTTP response, inspect its headers and body before adding automatic retries. Retrying an unchanged invalid key or hash will not correct the credential.

6. Reliability, performance, and cost considerations

  • Keep credentials server-side. Query parameters can appear in proxy logs, diagnostics, and monitoring systems. Avoid placing a customer key in public browser code or recording full request URLs in application logs.
  • Validate configuration at startup. Check that required environment variables exist and are non-empty. For secret-phrase accounts, verify that both the phrase and URL value used for signing are available to the same code path that builds the request.
  • Use bounded timeouts. Screenshot capture involves fetching a page, so allow an appropriate timeout and handle timeout errors separately from authentication codes.
  • Retry selectively. A transient network failure may merit a bounded retry with backoff. Do not repeatedly retry invalid_key, missing_key, or invalid_hash without changing configuration.
  • Separate credit errors from credentials. ScreenshotMachine documents no_credits for exhausted credits. Its pricing page says only fresh screenshots are charged; consult the current account and pricing information for plan details.
  • Protect signed requests. Treat the key and secret phrase as credentials. Restrict access, rotate them according to your organization’s process, and never include them in support screenshots or public issue reports.

Or skip the browser setup

If the task is to get a website screenshot and you do not need to keep troubleshooting ScreenshotMachine credentials, ScreenshotNeo provides a one-request screenshot API. See the ScreenshotNeo 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

ScreenshotNeo removes cookie banners, popups, and chat widgets 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 for ScreenshotNeo and get 1,000 free screenshots a month, with no card.

FAQ

Where does the ScreenshotMachine API key go?

In the key query parameter sent to https://api.screenshotmachine.com/.

Is invalid_hash the same as invalid_key?

No. The first identifies a bad or missing hash; the second identifies an invalid customer key. Use the response header to tell which one the API returned.

Should I add credits to fix invalid_key?

No. ScreenshotMachine documents exhausted credits as no_credits, a separate response.

What if the key copied from my account still fails?

Check the account and contact ScreenshotMachine through its contact page for account-specific API help.

Sources