ScreenshotNeo

BlogHow-to

How to Schedule Daily Website Screenshots Using Screenshotlayer and Cron

Run Screenshotlayer captures every day with cron. Save dated images, handle cache and errors, and keep scheduled jobs observable.

By the ScreenshotNeo team4 October 20268 min read

To schedule a daily Screenshotlayer capture, put the API request in a script that saves a dated image and exits with an error when the request fails, then run that script from cron. For a 02:30 daily run, the cron entry is 30 2 * * *. Use a deliberately chosen cache policy: Screenshotlayer’s archived specification documents a default cache TTL of 2,592,000 seconds (30 days), so a daily schedule alone does not ensure a fresh image.

The Screenshotlayer endpoint and options below come from an archived API specification and README. Verify the endpoint, HTTPS availability for your plan, parameter behavior, supported formats, and current quota in your account before deploying. The archived docs list http://api.screenshotlayer.com/api/capture and say paid customers can use the corresponding HTTPS endpoint. [Screenshotlayer API repository]

1. Prepare the request and credentials

Create or access a Screenshotlayer account and obtain its access key. The request requires access_key and the target url; include the full page URL with its protocol, such as https://example.com/. Do not put a live key in a public repository or log the complete request URL: the documented API sends the key in the query string.

Set credentials for the account that will run cron. For a simple single-user Linux host, add these to that user’s shell profile or a protected environment file loaded by the script:

export SCREENSHOTLAYER_ACCESS_KEY='YOUR_API_KEY'
export SCREENSHOTLAYER_URL='https://example.com/'

Restrict any file holding credentials so other local users cannot read it, and avoid printing the key in error messages. On managed systems, use the host’s secret store. Cron often runs with a smaller environment than an interactive shell, so explicitly load the protected file or define the needed variables in the script’s execution environment.

2. Create a capture script

This Bash script uses curl, encodes the page URL as a query parameter, writes to a date-based filename, checks the HTTP response, and appends a timestamped status line. It downloads to a temporary file first, so a failed or partial response does not replace a valid daily image. Set SCREENSHOTLAYER_ENDPOINT to the endpoint verified for your account. The example assumes the API returns the image bytes for a successful capture; check the live API’s response behavior before using it unchanged.

#!/usr/bin/env bash
set -u

ENDPOINT="${SCREENSHOTLAYER_ENDPOINT:-https://api.screenshotlayer.com/api/capture}"
OUT_DIR="${SCREENSHOT_OUTPUT_DIR:-/var/lib/site-shots}"
LOG="${SCREENSHOT_LOG:-/var/log/site-shots.log}"
: "${SCREENSHOTLAYER_ACCESS_KEY:?Set SCREENSHOTLAYER_ACCESS_KEY}"
: "${SCREENSHOTLAYER_URL:?Set SCREENSHOTLAYER_URL}"

mkdir -p "$OUT_DIR" "$(dirname "$LOG")" || exit 1
today="$(date +%F)"
out="$OUT_DIR/site-$today.png"
tmp="$out.tmp"

# Choose a cache policy. TTL is seconds. For a fresh capture, use force=1
# if the current API documentation confirms this parameter for your plan.
if http_code="$(curl --silent --show-error --location \
  --output "$tmp" --write-out '%{http_code}' \
  --get "$ENDPOINT" \
  --data-urlencode "access_key=$SCREENSHOTLAYER_ACCESS_KEY" \
  --data-urlencode "url=$SCREENSHOTLAYER_URL" \
  --data-urlencode 'format=PNG' \
  --data-urlencode 'ttl=86400')"; then
  if [[ "$http_code" == 2?? ]] && [[ -s "$tmp" ]]; then
    mv -- "$tmp" "$out"
    printf '%s OK %s\n' "$(date --iso-8601=seconds)" "$out" >> "$LOG"
    exit 0
  fi
  printf '%s ERROR HTTP %s; inspect response file %s\n' \
    "$(date --iso-8601=seconds)" "$http_code" "$tmp" >> "$LOG"
else
  printf '%s ERROR curl request failed\n' "$(date --iso-8601=seconds)" >> "$LOG"
fi
rm -f -- "$tmp"
exit 1

Save it as /usr/local/bin/capture-site.sh and make it executable with chmod 750 /usr/local/bin/capture-site.sh. The script’s format, ttl, and endpoint are configuration choices, not guarantees about current service behavior: confirm their names and accepted values against current Screenshotlayer documentation. If the service returns structured JSON errors with a successful HTTP status, add parsing for the documented response shape so the script does not mistake an API error body for an image.

3. Choose capture options and cache behavior

Option When to use it Considerations
fullpage=1 Capture the whole document instead of just the viewport. Long pages produce larger images and may take longer. Confirm the option spelling and limits in current docs.
viewport Control the browser viewport dimensions. Use a stable size if you compare screenshots over time; the archived spec lists the option but this dossier does not specify its exact syntax.
format Choose an output image format supported by the service. The archived project README mentions PNG, JPEG, and GIF; confirm the current supported values and response content type.
delay Allow a page extra time to render after navigation. Longer delays increase request duration. Prefer the shortest delay that accommodates the page’s content.
ttl Set a cache lifetime appropriate for the capture. The archived spec gives a 30-day default. A one-day TTL may suit daily jobs, but verify whether TTL is measured from capture time and how cache keys are formed.
force=1 Request a fresh capture rather than a cached image. Use only after confirming current semantics; a fresh request may count against the account’s allowance.

For a daily archive, decide whether you want a new rendering each day or are comfortable reusing an image while the page is unchanged. A shorter TTL controls reuse; the archived spec also lists force=1. Do not assume the scheduler bypasses caching. Multiple URLs or viewport variants mean multiple captures, so estimate volume as sites × variants × runs per month and compare it with the live plan allowance. The archived README’s free allowance of 100 snapshots per month is historical, not a verified current quota.

4. Add the job to cron

Use crontab -e as the user that owns the job, then add a line with absolute paths:

30 2 * * * /usr/local/bin/capture-site.sh >> /var/log/site-shots-cron.log 2>&1

Cron’s five time fields are minute, hour, day of month, month, and day of week. This example runs daily at 02:30 according to the host scheduler’s time basis. Cron is the system scheduler for commands at specified dates and times; see Ubuntu’s cron guide. Use crontab -l to inspect the installed entry.

  1. Run the script manually as the intended cron user and confirm the dated file appears.
  2. Check that the cron user can read its credential source, write the image directory, and append to the log.
  3. Inspect the crontab with crontab -l.
  4. After the scheduled time, check the log and output file. If the host sleeps or is offline at 02:30, traditional cron may miss the run; use an always-on host or a scheduler with missed-run catch-up if that requirement matters.

If the local timezone matters, verify the host’s cron timezone configuration. Daylight-saving changes can shift the apparent local run time depending on the scheduler and host configuration. Do not assume a UTC schedule is equivalent to local wall time.

5. Store and retain the screenshots

The example writes site-YYYY-MM-DD.png to a local directory. Dated filenames avoid overwriting previous captures, but they also accumulate storage. Set a retention policy that matches your audit needs, and back up images if they are important. Screenshotlayer’s archived specification also documents optional S3 and FTP destinations; verify current setup and transfer behavior before relying on them. [Screenshotlayer API repository]

Protect screenshot files as you would the page contents: captures can contain personal data, account details, or information exposed after login if your target is authenticated. Keep output directories private and define who can access and delete stored files.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. Its API accepts one GET request for a URL and can return PNG, JPEG, WebP, or PDF; see the ScreenshotNeo API docs. For a daily cron capture, put this request in a script and save its response under a dated filename:

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, newsletter popups, and chat widgets before capture. Bot checks, blank pages, failed loads, timeouts, and cache hits are never billed, and the response identifies the page verdict and billing status in headers. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Sign up free for ScreenshotNeo.

Troubleshooting

Symptom Likely cause What to do
No screenshot and no log entry Cron did not install the entry, ran under another user, or invoked a different script path. Check crontab -l for the owning user, use absolute paths, and inspect the host’s cron logs.
Missing or invalid access key The credential was not available in cron’s environment or was copied incorrectly. Load the protected credential source explicitly and check for whitespace or quoting errors without printing the secret.
Usage limit reached The account’s current allowance is exhausted. Check the account dashboard and request volume, including multiple sites and variants. Do not rely on archived quota figures.
Invalid URL The URL is malformed, lacks http:// or https://, or was not URL-encoded. Use the full URL and --data-urlencode for query parameters.
Old image appears every day The API returned a cached result under its TTL. Set a suitable TTL or use the documented force-refresh option after checking current semantics.
Image file contains an error message or is unusable The API may return a structured error body, or a non-image response may have been saved. Inspect HTTP status, response headers, and body; validate the content type and API error format before renaming the temporary file.
Permission denied or output missing The cron user cannot write the directory or log. Create the directories with suitable ownership and permissions, then run the script as the cron user.
Job runs at an unexpected local time The host timezone or daylight-saving behavior differs from expectations. Check the host’s timezone and cron configuration; express the schedule in the time basis the server actually uses.

Performance, reliability, and cost

  • Request duration: Full-page captures and added render delay can take longer than viewport captures. Set a timeout suitable for the target and make sure the scheduler does not start overlapping jobs.
  • Retries: A transient network failure can be retried with a small bounded backoff. Avoid tight retry loops, which can create duplicate requests or consume allowance. Do not retry invalid credentials, malformed URLs, or exhausted quota until corrected.
  • Observability: Keep both the script’s concise log and cron’s stderr output. For a production workflow, alert on a nonzero exit or on a missing expected dated file; otherwise unattended failures can remain unnoticed.
  • Cost: Calculate planned captures per month and verify current account terms. The archived 100-per-month free allowance is not a current plan promise. Forced refreshes and separate variants may affect usage; confirm billing semantics.
  • Data handling: Choose local or remote storage based on retention, access control, and backup needs. The dossier provides no cost or reliability comparison between local, S3, and FTP storage.

FAQ

Will cron run the job if the computer is switched off?

No. A traditional cron daemon must be running on an available host at the scheduled time. Use a continuously available machine or a scheduler that supports missed-run handling.

Does a daily cron entry guarantee a new screenshot daily?

No. The archived Screenshotlayer spec documents caching and a 30-day default TTL. Configure a shorter TTL or a force-refresh option after verifying current API behavior.

Can I save captures to S3 or FTP?

The archived Screenshotlayer specification lists both as optional destinations. Confirm current availability and configuration details in the live account documentation.

Can I safely include the API key in the cron line?

A crontab can be readable by users with sufficient system access, and command lines may be exposed through process inspection or logs. Prefer a protected environment or secret store, and do not log full query URLs.