Skip to main content
This page describes the controls that the Screenshotly API enforces and what you should do on your side. It covers behavior you can rely on when designing an integration; it is not a compliance certification.

API keys

  • Keys are random 256-bit values with a scr_ prefix. Screenshotly stores only a SHA-256 hash, so a key is shown in plaintext once, at creation.
  • Each key belongs to one workspace and can read only that workspace’s jobs and captures.
  • Keys created in the dashboard expire after 30 days. A workspace can have up to 10 active keys.
  • A revoked or expired key is rejected with 401 on the next request.
  • Rate limits and capture allowance belong to the workspace owner’s account, so a leaked key cannot raise them, but it can spend them.
What you should do: keep keys in a secret manager or environment variable, call the API only from servers, workers, or CI, use separate keys per environment, and revoke a key as soon as it appears in logs, client code, or a repository. See Managing API keys.

Target URL protection

Screenshotly only captures public web addresses. Before a capture starts, the url field must:
  • use http or https;
  • contain no username or password;
  • not be localhost or end in .localhost, .local, .internal, or .home.arpa; and
  • resolve only to public IP addresses.
Addresses in private, loopback, link-local (including the 169.254.169.254 cloud metadata address), carrier-grade NAT, documentation, benchmarking, multicast, and reserved ranges are blocked, for both IPv4 and IPv6. A blocked target returns 400 Unsafe URL. The same check runs on every request the page makes while rendering, including redirects, frames, scripts, and images. A public page cannot redirect or embed its way to an internal address. Schemes other than http, https, data, and blob are blocked inside the page too.

Credentials you send to target pages

Authenticated captures (Basic plan and above) can pass headers and cookies to the target page.
  • Cookie domain values must equal the target host or one of its parent domains, so a cookie cannot be sent to an unrelated site.
  • Hop-by-hop and proxy headers such as Host, Forwarded, and X-Forwarded-For are rejected.
  • Async job payloads, which may contain these headers, cookies, custom JavaScript, and webhook secrets, are encrypted with AES-256-GCM before they are written to the job queue. Webhook deliveries are encrypted the same way.
What you should do: use a dedicated, least-privilege test account for authenticated captures, prefer short-lived session cookies, and rotate them after sharing. Remember that whatever the page shows to that account appears in the captured image.
  • Async jobs and persisted (storage) captures are stored per workspace and deleted automatically at the end of the account’s retention period, 1–30 days (7 by default).
  • Downloads use signed, expiring links: 15 minutes for a resultUrl returned by GET /api/jobs/{id}, and 24 hours for webhook and storage links. Expired links are refused, and no link works after the file has been deleted.
  • Anyone who has an unexpired link can download the file. Treat links like credentials and do not post them in public channels.

Webhooks

Webhook URLs pass the same public-address checks as capture targets. Redirects are not followed, so a webhook cannot be bounced to an internal address. Set a secret and verify the X-Screenshotly-Signature HMAC-SHA256 header on every delivery. See Webhooks.

Teams and access

Every account has an isolated personal workspace. Team workspaces have owner, admin, and member roles. A key can be revoked by the member who created it or by a workspace owner or admin. See Teams, usage, and retention.

Deleting your data

The account owner can delete application data from Account controls after canceling any active subscription. This removes keys, jobs, request history, billing references, and stored capture files. The sign-in identity is managed separately and is not deleted by this action.

Reporting a security issue

Email [email protected] with steps to reproduce. Please do not include live API keys or other secrets in the report.