How to Capture a Password-Protected Web App with ScreenshotMachine CLI
Pass a valid app session cookie to ScreenshotMachine with curl, save the image, and check whether it shows the protected page or an error.
Direct answer: To capture a page behind an app login with ScreenshotMachine, obtain a valid session cookie through an authorized login, then send it in the documented cookies parameter along with your ScreenshotMachine customer key and the target URL. The customer key authorizes the screenshot request; it does not sign in to the target app. Check the response and the image, because an error image or login page can look like a successful capture.
ScreenshotMachine’s documented API uses HTTP GET. Its documentation describes cookies as semicolon-separated name=value pairs that must be percent-encoded. It does not establish support for interactive form login or HTTP Basic credentials. See the ScreenshotMachine screenshot API documentation for the current parameter details.
1. Get a session cookie through an authorized login
Sign in to the web app using an account and process you are authorized to use. Retrieve the relevant session cookie from your browser’s developer tools or from your own login flow. Cookie names vary by application; the example below uses session as a placeholder.
- Use a cookie that is valid for the exact app page you plan to capture.
- Do not commit the cookie, customer key, or a generated request URL containing them to source control.
- Treat the cookie as a password: avoid putting it in shared logs, shell history, public code, or a client-side page.
- If the app uses multiple cookies or a CSRF-bound session, determine which values its authenticated page request actually needs.
This method passes an existing session to the capture request. It does not automate the login form, solve multi-factor authentication, or refresh an expired session.
2. Capture with curl
This shell example URL-encodes the target URL and cookie parameter, then writes the response body to app.png. Replace the placeholders with your ScreenshotMachine customer key, target URL, and current session cookie.
curl -sS -G "https://api.screenshotmachine.com/" \
--data-urlencode "key=YOUR_SCREENSHOTMACHINE_KEY" \
--data-urlencode "url=https://app.example.com/dashboard" \
--data-urlencode "cookies=session=YOUR_SESSION_VALUE" \
--data-urlencode "dimension=1366x900" \
--data-urlencode "format=png" \
--data-urlencode "cacheLimit=0" \
-D response-headers.txt \
-o app.png
--data-urlencode encodes the parameter value for the GET request. For more than one cookie, provide a semicolon-separated value, for example session=VALUE; preference=dark; encode the complete value as one parameter. Avoid manually double-encoding it.
Inspect response-headers.txt for X-Screenshotmachine-Response, then open app.png. The API may return an image describing an error, so the existence of a file alone does not prove the authenticated page loaded.
3. Options to tune the capture
| Parameter | Use | Documented values or guidance |
|---|---|---|
key |
Your ScreenshotMachine customer key. | Required for the API request; distinct from the target app cookie. |
url |
The page to capture. | Required. URL-encode it; curl --data-urlencode handles this. |
cookies |
Target app session and other required cookies. | Semicolon-separated name=value pairs; percent-encoding is required. |
dimension |
Viewport width and height, or full-length capture. | WIDTHxHEIGHT; documented range is width 100–1920 and height 100–9999. full is supported for full-length captures. |
format |
Output image format. | jpg, png, or gif. |
device |
Preset device rendering. | desktop, phone, or tablet. |
delay |
Wait before capture for page content to render. | For long pages or content that loads late, the vendor suggests a longer delay, such as 2000 ms or more. |
cacheLimit |
Control screenshot cache freshness. | 0–14 days; 0 requests a fresh screenshot. |
Use a full-length dimension such as 1366xfull when the complete page matters. For a dashboard whose contents arrive after initial load, increase delay and check whether the rendered page contains the expected data. A longer delay can increase capture time. Setting cacheLimit=0 helps avoid a cached image when session state or page content has changed.
4. Python example
This example uses Python’s requests library. It URL-encodes the query parameters, saves the response bytes, and prints the documented error header when present.
import os
import requests
params = {
"key": os.environ["SCREENSHOTMACHINE_KEY"],
"url": "https://app.example.com/dashboard",
"cookies": "session=" + os.environ["APP_SESSION_COOKIE"],
"dimension": "1366x900",
"format": "png",
"cacheLimit": "0",
}
response = requests.get(
"https://api.screenshotmachine.com/",
params=params,
timeout=90,
)
response.raise_for_status()
with open("app.png", "wb") as image_file:
image_file.write(response.content)
print("ScreenshotMachine response:", response.headers.get("X-Screenshotmachine-Response", "no error header"))
print("Saved app.png; inspect it to confirm the authenticated page rendered.")
Install the dependency with python -m pip install requests. Set SCREENSHOTMACHINE_KEY and APP_SESSION_COOKIE in the process environment. The code handles one cookie; for multiple cookies, construct the semicolon-separated value required by the API.
5. Node.js example
The ScreenshotMachine-linked Node.js repository documents a package-based example for generating a screenshot API URL and saving the response stream. The following standalone Node.js example uses built-in fetch to make the equivalent GET request and save the returned bytes.
import { writeFile } from "node:fs/promises";
const params = new URLSearchParams({
key: process.env.SCREENSHOTMACHINE_KEY,
url: "https://app.example.com/dashboard",
cookies: `session=${process.env.APP_SESSION_COOKIE}`,
dimension: "1366x900",
format: "png",
cacheLimit: "0",
});
const response = await fetch(
`https://api.screenshotmachine.com/?${params.toString()}`
);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}
const errorCode = response.headers.get("X-Screenshotmachine-Response");
await writeFile("app.png", Buffer.from(await response.arrayBuffer()));
console.log("ScreenshotMachine response:", errorCode ?? "no error header");
console.log("Saved app.png; inspect it to confirm the authenticated page rendered.");
Run it in a Node.js environment that supports built-in fetch, with the same two environment variables set. The request URL contains the encoded cookie parameter; keep it out of logs.
6. Understand the login and credential boundary
There are two separate credentials in this workflow:
- ScreenshotMachine customer key: identifies and authorizes your use of ScreenshotMachine.
- Target app session cookie: represents a session already authenticated to the app and is sent using
cookies.
The reviewed ScreenshotMachine documentation lists target cookies and options to customize Accept-Language and User-Agent. It does not document an interactive login sequence or a target Basic Authorization field. A URL that requires authorization may produce an invalid_url error image. Do not infer that an API key signs into the app or that a login form can be automated by this request.
Cookie behavior across redirects, subdomains, and resources loaded from other origins is not specified in the reviewed docs. If the main page loads but its data does not, confirm which requests require authentication and whether the supplied cookie is valid for those requests.
7. Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
| Image shows a login screen | The cookie is missing, expired, malformed, or not accepted for that page. | Sign in again through the authorized flow, retrieve a fresh cookie, verify its name and value, and ensure it is passed as a percent-encoded name=value parameter. |
invalid_url in X-Screenshotmachine-Response |
The URL is invalid or the target requires authorization; the vendor includes HTTP 401 authorization-required cases under this code. | Check the URL and attempt the documented cookie method. If the target needs an unsupported interactive login or credential type, the reviewed docs do not establish that ScreenshotMachine can handle it. |
invalid_key or missing_key |
The ScreenshotMachine customer key was omitted or is not valid. | Check the key parameter and account key. Do not substitute the app cookie. |
missing_url |
The required target URL was not supplied. | Include the complete URL in url and use URL encoding. |
no_credits |
The ScreenshotMachine account lacks available credits. | Check the account’s available credits before retrying. |
invalid_selector or invalid_crop |
A selector or crop option is invalid. | Review any selector or crop parameters and remove them temporarily to isolate the request. |
system_error or no useful image |
The capture request failed, or the returned image is an error image. | Inspect X-Screenshotmachine-Response, verify the output image, and retry only after checking the URL, credentials, and capture options. |
| Cookie parameter appears ignored | It may be incorrectly encoded, double-encoded, or missing required companion cookies. | Pass the semicolon-separated cookie string as one encoded parameter. With curl, use --data-urlencode; with Python or Node, use query-parameter encoders. Avoid manually encoding it twice. |
| Page shell appears but data is blank | App data may load asynchronously or require a session on another origin. | Try a longer delay, verify the session in the target’s own authorized browser, and check the app’s authenticated resource requests. Cross-origin cookie behavior is not specified in the reviewed docs. |
| Old screenshot despite a new session | A cached capture may be served. | Set cacheLimit=0 to request a fresh screenshot. |
| Output file is not a valid image | The response may be an error image, HTTP failure, or unexpected body. | Check HTTP status and X-Screenshotmachine-Response; open the file and verify its contents instead of treating file creation as success. |
The documented error codes include invalid_hash, invalid_key, invalid_url, missing_key, missing_url, no_credits, invalid_selector, invalid_crop, and system_error. The response header and the rendered image are both useful evidence when diagnosing a protected-page capture.
8. Reliability, performance, and credential handling
- Verify content, not just transport: a successful HTTP response or saved image does not prove the target session worked. Inspect the error header and image for a login page, error image, or missing app data.
- Refresh sessions deliberately: cookies can expire or become invalid. The reviewed docs do not say ScreenshotMachine refreshes sessions, so arrange a fresh cookie through your authorized login process.
- Balance wait time and latency: use enough delay for client-rendered content and late images. The vendor suggests 2000 ms or more for some long pages; only increase it when needed.
- Choose cache freshness intentionally: set
cacheLimit=0when changes to account-specific content must appear in the output. A nonzero cache limit can be useful when freshness is less important. - Protect secrets: GET parameters can appear in request URLs and logs. Keep these requests server-side, do not expose the generated URL to a browser or analytics, and avoid logging the cookie or full URL.
- Retry with care: first distinguish a transient capture error from an expired cookie or invalid request. Repeating a request with the same expired session will not fix the cause.
Or skip the browser setup
ScreenshotNeo is a screenshot API and MCP server. Pass the target URL in one request; consult the ScreenshotNeo API documentation for the API and available options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo accepts cookie and consent banners like a visitor and removes 60+ known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and responses identify the page verdict and billing status. Its MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots per 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 the ScreenshotMachine API key unlock my app?
No. It authorizes the capture API. Access to the target app comes from a valid target-site session cookie passed separately.
Can ScreenshotMachine submit my login form?
The reviewed official documentation does not establish interactive login automation. The documented route to try is passing an existing cookie.
Can I use HTTP Basic authentication?
Basic-auth support for the target is not established by the reviewed ScreenshotMachine documentation. Do not assume a custom header or the API key is equivalent.
Can the capture service renew my app session?
The reviewed documentation does not specify session renewal. Obtain a valid cookie using your app’s authorized login process.
Why did curl save a file when authentication failed?
The API can return an error image, and a protected target can trigger invalid_url. Check the response header and open the image to verify its contents.
Sources
- ScreenshotMachine website screenshot API documentation — request method, cookie parameter, capture options, and documented response errors.
- ScreenshotMachine Node.js example repository — package setup and screenshot saving example.


