> ## Documentation Index
> Fetch the complete documentation index at: https://docs.screenshotly.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Security

> How Screenshotly protects API keys, blocks private-network targets, encrypts queued payloads, signs downloads and webhooks, and deletes captures.

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](https://docs.screenshotly.app/guides/managing-tokens.md).

## 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.

## 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 `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](https://docs.screenshotly.app/guides/webhooks.md#verify-the-signature).

## 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](https://docs.screenshotly.app/guides/teams-and-usage.md).

## Deleting your data

The account owner can delete application data from
[Account controls](https://screenshotly.app/dashboard/settings) 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 [support@screenshotly.app](mailto:support@screenshotly.app) with steps to
reproduce. Please do not include live API keys or other secrets in the report.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.