ScreenshotNeo

BlogHow-to

How to Generate Website Thumbnails in Bulk with ScreenshotMachine CLI for an Indian Directory

Build a local bulk thumbnail workflow with ScreenshotMachine’s HTTP API, curl, and a URL list. Learn how to configure captures, handle failures, and validate files.

By the ScreenshotNeo team4 October 20269 min read

ScreenshotMachine documents an HTTP GET screenshot API and a Bash curl example; the available documentation does not establish a separate official CLI binary or a provider-side batch endpoint. To generate thumbnails in bulk, read one URL per line from a file and make one API request per URL from a local shell script. For consistent directory cards, set the same 320x240 dimensions and image format for each request, then check every response and output file before importing the results.

This guide adapts ScreenshotMachine’s documented single-request pattern into a local workflow. The loop is an implementation example, not a tested script or an official bulk client. Confirm the current account limits and request policies before processing a large directory.

1. Understand the CLI and bulk workflow

ScreenshotMachine’s documented command-line approach is Bash plus curl calling its HTTP API. The documented request includes one url parameter. A local loop can repeat that request for a list of sites, but that does not mean ScreenshotMachine processes a batch on its servers.

  1. Prepare a UTF-8 text file with one complete site URL per line.
  2. Keep the API key in an environment variable, not in the URL list or source control.
  3. For each nonblank, noncomment line, send one encoded GET request.
  4. Save the response under a stable filename and record whether the request succeeded.
  5. Validate the files and review failures before importing thumbnails.

For an Indian directory, use the site’s canonical URL in each row. The available documentation does not establish that ScreenshotMachine captures from India or that a language setting simulates an Indian visitor location. If a site varies by locale, test the specific page and use the documented language or cookie options where appropriate.

2. Prepare the URL list and API key

Create urls.txt with one URL per line. Blank lines and lines beginning with # are skipped by the example below.

https://example.in/
https://shop.example.in/
# Add one URL per line

Obtain the API key through ScreenshotMachine signup, then export it in the shell running the script:

export SCREENSHOTMACHINE_KEY='YOUR_API_KEY'

The API also describes an optional secret phrase and URL-derived MD5 hash. When a secret phrase is configured, requests with a missing or incorrect hash are ignored. Keep both credentials out of public client-side code and public repositories. Follow the provider’s hash instructions for the exact request signature; this example assumes an account configuration that accepts the shown key-based request.

3. Choose consistent thumbnail settings

Setting Documented choices or behavior Directory guidance
Dimensions 320x240 is explicitly given as a website thumbnail size. Width is documented from 100 to 1920 pixels; height from 100 to 9999. full can request a full-length capture. Use the same dimensions for a consistent card grid. Check that the resulting aspect ratio fits your design.
Device desktop, phone, or tablet. Typical examples include 1024×768 for desktop and 480×800 for phone. Use desktop for standard directory listings. Capture a separate phone variant if the directory specifically previews mobile layouts.
Format JPG, PNG, and GIF are listed; JPG is the default. Choose one format for simpler imports. Use another only when your pipeline needs it.
Delay The documented choices run from 0 through 10000 milliseconds. The documentation suggests a larger delay, such as 2000 or more, for long pages with images or animations. Start with a modest delay and increase it for pages that render late. Longer delays make each request take longer.
Cache age cacheLimit accepts 0 through 14 days and defaults to 14. Zero requests a fresh screenshot each time. Use zero when refreshing directory listings; allow a longer age when reusing recent captures is acceptable.

The API also documents controls such as accept-language, custom user agent, CSS selector capture, click, hide, cookies, and crop. Apply these only when a site needs them; the exact supported values and request syntax should be checked in ScreenshotMachine’s current API reference.

4. Generate thumbnails with Bash and curl

Save the following as capture-thumbnails.sh. It creates one request per URL, uses URL encoding for reserved characters, and writes files into the requested output directory. The filename conversion is intentionally simple: production workflows need explicit collision handling, especially when several URLs share a host or differ only by path or query string.

#!/usr/bin/env bash
set -euo pipefail

: "${SCREENSHOTMACHINE_KEY:?Set SCREENSHOTMACHINE_KEY in the environment}"
input=${1:?Usage: ./capture-thumbnails.sh urls.txt output-directory}
outdir=${2:?Usage: ./capture-thumbnails.sh urls.txt output-directory}
mkdir -p "$outdir"

while IFS= read -r url || [[ -n "$url" ]]; do
  [[ -z "$url" || "$url" == \\#* ]] && continue

  # Minimal filename conversion; use a collision-proof mapping in production.
  name=$(printf '%s' "$url" | sed -E 's#^https?://##; s#[^A-Za-z0-9._-]+#_#g')
  curl --fail --silent --show-error --get 'https://api.screenshotmachine.com' \
    --data-urlencode "key=$SCREENSHOTMACHINE_KEY" \
    --data-urlencode "url=$url" \
    --data-urlencode 'dimension=320x240' \
    --data-urlencode 'device=desktop' \
    --data-urlencode 'format=jpg' \
    --data-urlencode 'cacheLimit=0' \
    --data-urlencode 'delay=1000' \
    --output "$outdir/$name.jpg"
done < "$input"

Make it executable and run it with the input list and destination directory:

chmod +x capture-thumbnails.sh
./capture-thumbnails.sh urls.txt thumbnails

The script uses the provider’s documented request pattern, with 320x240 as the thumbnail size. It does not add retries or parallel requests. That keeps the basic example straightforward; for a large run, add measured concurrency, a delay between requests if required by your account, a log of each URL and outcome, and bounded retries for transient failures. Check current provider limits before increasing throughput.

5. Add safer filenames and failure records

The sample filename derived from the whole URL can become long, can contain awkward encodings, and can collide after sanitization. It may also treat query strings as part of a filename even when the directory considers two URLs the same page. A reliable import process should map each input record to a unique identifier, such as a directory record ID or a stable hash of the canonical URL, and keep a separate CSV mapping identifier, original URL, output path, HTTP result, response header, and retry count.

For every request, inspect both the curl exit status and the provider’s X-Screenshotmachine-Response header. Do not mark a file successful just because an output path exists: failed responses may leave an unusable file. The provider documents error codes including invalid_key, invalid_url, missing_url, no_credits, invalid_selector, invalid_crop, and system_error.

6. Configure locale, freshness, and page behavior

  • Localized pages: Use the documented accept-language option when the site selects content by browser language. This is not evidence of a particular capture region.
  • Cookie-dependent content: The documented API includes cookies. Supply only the cookies needed for the page state you intend to capture, and avoid exposing sensitive session values in logs.
  • Late-loading content: Raise delay for pages with slow images or animations, within the documented range. This increases the duration of each capture.
  • Targeted previews: Use selector capture or crop controls if a full viewport contains irrelevant material. Verify the selector against each site template; invalid_selector is a documented error.
  • Fresh versus cached: Use cacheLimit=0 to request fresh shots. A higher value, up to the documented 14-day range, may reuse a recent capture and reduce duplicate work.
  • Responsive variants: Keep device and dimensions fixed within each output set. If both desktop and phone previews are required, store them as separate variants rather than mixing sizes under one filename scheme.

7. Validate and import the output

  1. Count input records, successful responses, failed requests, and saved files; investigate any mismatch.
  2. Check that every output is a decodable image in the selected format and has the expected dimensions.
  3. Open a sample from each type of site in the directory, including pages with redirects, locale selection, cookie prompts, and slow content.
  4. Review duplicate or sanitized filenames before import, and retain the original URL-to-file mapping.
  5. Re-run only failed or stale entries rather than blindly recapturing the full directory.

For Indian-language domains or internationalized domain names, use valid canonical URLs and preserve the original URL in your mapping. Avoid deriving the permanent record identity from a lossy ASCII filename conversion.

8. Troubleshoot common problems

Symptom or code Likely cause What to do
invalid_key The key is incorrect, missing, or not being passed as expected. Check the environment variable and account key; do not print the key into shared logs.
no_credits The account has no credits available for the request. Check the account balance or plan before resuming the batch. Log the failed URL so it can be retried later.
missing_url / invalid_url A blank or malformed URL reached the request, or a URL was not encoded correctly. Skip blank lines, require a complete URL, and keep --data-urlencode for URL values with reserved characters.
invalid_selector A requested CSS selector is absent or invalid for that page. Check the selector on the target page, or remove selector capture for pages with different templates.
invalid_crop Crop parameters are malformed or outside accepted constraints. Validate crop coordinates and dimensions against the API reference, then retry that URL.
system_error or curl transport failure A transient service, network, or capture failure may have occurred. Record the response and retry with a bounded backoff. Avoid an unlimited retry loop.
HTML or error content saved with an image extension The response was treated as an image without validating the provider result. Check curl status and X-Screenshotmachine-Response; validate image decoding before import.
Missing images or animation frame The page had not finished rendering when captured. Increase the documented delay selectively and recapture affected pages.
Wrong language or regional page The site used a language, cookie, IP, or account signal not represented by the request. Try the documented language or cookie controls. The sources do not establish regional rendering location.
Output overwritten or duplicated Different URLs collapsed to the same sanitized filename. Use a unique record ID or stable URL hash in filenames and retain a mapping table.

9. Performance, reliability, and cost planning

A local loop makes requests sequentially, so total runtime grows with the number of URLs and each page’s capture delay and load time. A larger configured delay improves the chance that slow content appears but also lengthens each request. Caching may avoid recapturing a recent page when that freshness is acceptable. If adding concurrency, start conservatively and confirm current service limits and account rules; the reviewed documentation does not establish a numeric concurrency or rate limit.

For reliable operation, make runs resumable: record success per URL, retry only eligible failures, cap retry attempts, and keep credentials out of logs. Treat the provider’s response header as part of the result, not just the HTTP transport status. The available research does not establish current ScreenshotMachine pricing, quotas, throughput, or regional capture quality, so estimate cost and capacity from the current account information rather than assuming a rate.

10. Or skip the browser setup

ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF, and its options include full-page and element captures, device presets, custom CSS and JavaScript, cookies and headers, waiting controls, caching, bulk capture, and more. See the ScreenshotNeo API documentation.

For a single request with curl:

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -o shot.webp

Python:

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)

Node.js:

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', new Uint8Array(await res.arrayBuffer()));

For a directory batch, repeat the request for each URL or use ScreenshotNeo’s bulk capture option. 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 for ScreenshotNeo’s free plan.

11. Frequently asked questions

Is there an official ScreenshotMachine CLI binary?

The cited documentation shows Bash and curl calls to its HTTP API. It does not establish a standalone CLI binary.

Does ScreenshotMachine have a bulk endpoint?

The reviewed request example is for one URL. The bulk method shown here is a local loop issuing repeated single-URL requests.

Can one 320×240 image represent both desktop and mobile layouts?

It is one capture at a selected device configuration. Capture separate variants if your directory needs both responsive layouts.

Can I assume the screenshot is rendered from India?

No. The reviewed sources do not establish the capture region. Language and cookies can influence page content, but they do not prove geographic rendering.