How to use ScreenshotMachine with Puppeteer for website screenshot jobs
Use ScreenshotMachine as a hosted screenshot API in a Puppeteer job, or capture the browser page directly with Puppeteer. See runnable examples, settings, and troubleshooting.
To use ScreenshotMachine in a Puppeteer-based screenshot job, make an HTTP GET request to ScreenshotMachine’s hosted API with your API key, target URL, and capture options, then save the returned image bytes. Puppeteer does not need to provide the browser for this hosted capture. Use Puppeteer’s own page.screenshot() when you need an image of the page and state already open in its browser. The two capture paths are separate; the reviewed documentation does not describe a first-party Puppeteer adapter.
Choose the capture path
| Need | Use | What happens |
|---|---|---|
| A hosted screenshot of a URL with ScreenshotMachine settings | ScreenshotMachine API request | Your job sends an HTTP GET request; the service captures the requested URL and returns image data. |
| A screenshot of a page already opened or controlled by your Puppeteer code | page.screenshot() |
Puppeteer captures its own browser page and returns screenshot bytes asynchronously. |
| Browser automation or page preparation, followed by a hosted capture | Use both as separate steps | Automate with Puppeteer where needed, then call ScreenshotMachine for its hosted URL capture. Do not assume the hosted service captures Puppeteer’s existing page state. |
For a simple URL capture, an HTTP call is enough. Use Puppeteer when the workflow requires browser-side navigation, interaction, or access to state in that browser. Puppeteer documents Page.screenshot() as its own page screenshot operation. ScreenshotMachine documents a distinct HTTP screenshot API.
Request a ScreenshotMachine capture from Node.js
Keep the ScreenshotMachine API key in server-side configuration, such as an environment variable. Do not expose it in a public page or commit it to source control. The API guide also describes an optional secret phrase and a URL-plus-secret MD5 hash, and recommends protecting requests made from public HTML pages.
The following runnable Node.js script makes the hosted API request, checks for an HTTP error, and writes the image response to a file. Set SCREENSHOTMACHINE_KEY before running it. It uses Node.js’s built-in fetch and URLSearchParams so reserved characters in the target URL are encoded as query parameters.
import { writeFile } from 'node:fs/promises';
const key = process.env.SCREENSHOTMACHINE_KEY;
if (!key) throw new Error('Set SCREENSHOTMACHINE_KEY first');
const params = new URLSearchParams({
key,
url: 'https://example.com',
dimension: '1366x768',
device: 'desktop',
format: 'png',
cacheLimit: '0',
delay: '2000'
});
const response = await fetch(`https://api.screenshotmachine.com/?${params}`);
if (!response.ok) {
throw new Error(`ScreenshotMachine returned HTTP ${response.status}`);
}
const image = Buffer.from(await response.arrayBuffer());
await writeFile('screenshot.png', image);
console.log(`Saved ${image.length} bytes to screenshot.png`);
Run it with SCREENSHOTMACHINE_KEY set to your API key. For example, in a shell, export the variable before invoking your Node.js file. The extension should match the requested format. The request parameters and their documented values are listed in the ScreenshotMachine API guide.
Use Puppeteer’s own screenshot operation
If you already have a Puppeteer page and need exactly that page’s current state, capture it directly. This script launches Chromium, navigates to a URL, waits for the document load event, and saves a PNG.
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({ headless: true });
try {
const page = await browser.newPage();
await page.setViewport({ width: 1366, height: 768 });
await page.goto('https://example.com', { waitUntil: 'networkidle2' });
await page.screenshot({ path: 'puppeteer.png', fullPage: true });
} finally {
await browser.close();
}
Install Puppeteer in your project according to its official setup instructions. networkidle2 is a navigation wait condition, not proof that every animation, lazy image, or application-specific task has finished. If you need a particular element or state, wait for that condition explicitly before taking the screenshot.
Call ScreenshotMachine with cURL or Python
cURL
This command URL-encodes query parameters, saves the response body, and fails on HTTP error status codes. Replace the example URL and provide your key through an environment variable.
curl --fail --get 'https://api.screenshotmachine.com/' \
--data-urlencode "key=$SCREENSHOTMACHINE_KEY" \
--data-urlencode 'url=https://example.com' \
--data-urlencode 'dimension=1366x768' \
--data-urlencode 'device=desktop' \
--data-urlencode 'format=png' \
--data-urlencode 'cacheLimit=0' \
--data-urlencode 'delay=2000' \
--output screenshot.png
Python
Install the HTTP client with python -m pip install requests. The script checks the HTTP status and writes the response bytes as-is.
import os
import requests
key = os.environ['SCREENSHOTMACHINE_KEY']
params = {
'key': key,
'url': 'https://example.com',
'dimension': '1366x768',
'device': 'desktop',
'format': 'png',
'cacheLimit': '0',
'delay': '2000',
}
response = requests.get(
'https://api.screenshotmachine.com/',
params=params,
timeout=90,
)
response.raise_for_status()
with open('screenshot.png', 'wb') as image_file:
image_file.write(response.content)
Configure the capture
ScreenshotMachine’s API uses an HTTP GET request. Its guide marks key and url as required. The options below are the relevant documented controls for screenshot jobs.
| Parameter | Use and documented values | Practical note |
|---|---|---|
dimension |
Width and height as [width]x[height]; width 100–1920, height 100–9999, or full for full-page height. |
Choose the viewport dimensions your output needs. A full-page capture can require more time than a viewport capture. |
device |
desktop, phone, or tablet. |
Pair the device choice with the intended dimensions and layout. |
format |
jpg, png, or gif. |
Save the response with a matching file extension and downstream image handling. |
cacheLimit |
0 through 14 days; fractional values can request shorter intervals. | 0 requests a fresh screenshot. A positive value permits an acceptable cached image within that age. |
delay |
0–10,000 milliseconds. | Waits before capture. ScreenshotMachine suggests a longer delay, such as 2,000 ms or more, for some full-page captures with late images or animation; this does not guarantee complete rendering. |
zoom |
10–400 percent. | The guide says optimization may ignore zoom for screenshots smaller than typical device dimensions. |
click |
A CSS selector to click. | Use when the page needs an interaction before the image is captured. |
selector |
A CSS selector for an element capture. | Use for a component or region instead of the whole page. |
cookies |
Cookie data supplied as a request parameter. | Percent-encode the value and take care not to expose sensitive session cookies in logs or public URLs. |
| Language and user agent | Accept-Language and User-Agent request settings. | Percent-encode values that contain reserved URL characters. |
crop |
x,y,width,height in pixels. |
Coordinates refer to the requested image area; ensure the crop dimensions fit the capture. |
Full-page screenshots and dynamic pages
Use dimension with a full-page height when the entire document is needed. Pages that load images lazily or animate content may not be ready at the first possible capture moment. The vendor suggests using a delay of 2,000 ms or more for some full-page cases, but a fixed delay is only a timing allowance. If completeness matters, verify the output and tune the delay for the target page.
Freshness and caching
Set cacheLimit=0 when the job requires a fresh capture. For repeat captures where a recent image is acceptable, allow a cache interval to reduce redundant work. The guide permits values up to 14 days and fractional intervals for shorter cache ages. Choose based on how frequently the page changes and how fresh the deliverable must be.
Common errors and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| Request rejected or no useful image returned | The API key or target URL is missing or invalid. | Confirm both key and url are present, and check the key in server-side configuration. |
| URL works in a browser but breaks in the API request | Reserved characters in the URL or other parameter values were not encoded. | Build query parameters with URLSearchParams, Python params, or cURL --data-urlencode. Avoid concatenating unescaped query strings. |
| Image is stale | A cached capture is within the requested cache age. | Use cacheLimit=0 for a fresh capture or reduce the allowed age. |
| Images or animated content are missing | The page had not finished rendering when capture began. | Increase delay within the documented limit and inspect whether the page needs a longer application-specific wait. A delay cannot guarantee that third-party resources finish. |
| Output has the wrong framing or size | Dimension, device, zoom, or crop settings do not match the intended result. | Check the dimension range and format, verify device choice, and review crop coordinates. Remember the documented zoom caveat for small screenshots. |
| Element capture is empty or the wrong area is captured | The CSS selector does not match the intended element on the rendered page. | Check selector spelling and confirm the element exists after page rendering. For a Puppeteer-owned page, wait for the element and use Puppeteer’s screenshot API instead. |
| Node.js or Python reports a file or network exception | The request failed, timed out, or the output path is not writable. | Check network access and permissions, set a suitable client timeout, test HTTP status before writing, and ensure the destination directory exists. |
| Secret appears in logs or browser history | Credentials were placed in a public URL or logged query string. | Keep requests server-side, restrict logging of credential-bearing URLs, and follow the vendor’s guidance on its optional secret phrase and URL-plus-secret MD5 hash for public HTML use. |
Performance, reliability, and cost considerations
- Keep capture jobs bounded. Pick the smallest dimensions and capture area that satisfy the output requirement. Full-page images and longer waits can increase the amount of work and job latency.
- Set waits to the page. A fixed delay can help with late content but adds that time to the job even when the page loads quickly. Use only the wait the page needs and inspect outputs for dynamic pages.
- Choose cache freshness deliberately. A nonzero
cacheLimitcan reuse an eligible recent capture; set it to zero when stale output is unacceptable. - Handle failures at the request boundary. Check HTTP status, use a client timeout, preserve useful error context without logging credentials, and write the output only after a successful response.
- Plan service cost from the vendor’s current terms. The reviewed API documentation specifies capture options but does not provide a price or performance benchmark. Check ScreenshotMachine’s current commercial terms before estimating recurring job cost; do not infer speed or reliability from the settings alone.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF. It is an alternative to try first when you want a hosted capture without managing a browser: cookie banners, newsletter popups, and chat widgets are removed before the shot; bot checks, blank pages, failed loads, and cache hits are not billed; and its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf.
For example, this cURL command saves a WebP screenshot:
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 request details. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Sign up for free and get 1,000 screenshots a month with no card.
FAQ
Does ScreenshotMachine have a Puppeteer plugin?
The reviewed official sources document an HTTP API and Puppeteer’s separate page screenshot method, but do not document a first-party adapter. Treat the API request as a separate step in your job.
Can I capture the exact page open in Puppeteer through ScreenshotMachine?
The documented ScreenshotMachine request captures a URL through its hosted service. For the exact browser state controlled by your Puppeteer code, use page.screenshot().
Does adding a delay guarantee every page element is ready?
No. A delay only waits the specified time. Dynamic pages can still have unfinished animations, late resources, or application work after that interval.
Can I request a fresh screenshot every time?
Yes. The API guide documents cacheLimit=0 as a request for a fresh screenshot.


