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
401on 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.
Target URL protection
Screenshotly only captures public web addresses. Before a capture starts, theurl field must:
- use
httporhttps; - contain no username or password;
- not be
localhostor end in.localhost,.local,.internal, or.home.arpa; and - resolve only to public IP addresses.
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 passheaders and cookies
to the target page.
- Cookie
domainvalues 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, andX-Forwarded-Forare 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.
Captured files and download links
- 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
resultUrlreturned byGET /api/jobs/{id}, and 24 hours for webhook andstoragelinks. 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 asecret and verify the X-Screenshotly-Signature HMAC-SHA256 header on every
delivery. See Webhooks.