# ScreenshotLens Docs - complete documentation > ScreenshotLens turns a public page URL into a screenshot or a scrolling video over a REST API. This file is every documentation page concatenated as Markdown, in reading order. Canonical HTML lives at https://docs.screenshotlens.com/docs. --- # Overview Source: https://docs.screenshotlens.com/docs Summary: ScreenshotLens turns a public page URL into a screenshot or a scrolling video, billed in prepaid credits. Every integration follows the same path: create an API key in the dashboard, build the request in the Playground, then call the same URL from your server. ## Base URLs | Surface | URL | | --------- | ------------------------------------------------------------------ | | API | `https://api.screenshotlens.com` | | Dashboard | [`https://app.screenshotlens.com`](https://app.screenshotlens.com) | ## What you can capture | Capture | Request | Cost | | -------------------- | ------------------------------------------- | --------- | | Viewport screenshot | `GET /v1/screenshots` | 1 credit | | Full-page screenshot | `GET /v1/screenshots` with `full_page=true` | 2 credits | | Rolling video | `GET /v1/videos/rolling` | 5 credits | New accounts start with 100 credits, so you can integrate before buying anything. ## Where to go next [Quickstart](https://docs.screenshotlens.com/docs/quickstart) takes you from a new account to a working request in four steps. For exact parameters, defaults, and limits, go straight to the [Screenshot API](https://docs.screenshotlens.com/docs/api/screenshots) or the [Rolling Video API](https://docs.screenshotlens.com/docs/api/rolling-video). # Quickstart Source: https://docs.screenshotlens.com/docs/quickstart Summary: Create an API key and send your first ScreenshotLens request. Follow this once to get a successful capture, then tune the parameters. ### Create an API key Sign in at [app.screenshotlens.com](https://app.screenshotlens.com) and open **API keys**. New accounts start with 100 credits, which is enough to cover this page. Name the key after the environment that will call the API (`Production`, `Staging`, `CI`) so usage stays easy to trace. ### Send a screenshot request While integrating, set `response_type=json`. The response gives you the stored asset URL and the credits charged instead of raw image bytes. ```bash curl -G "https://api.screenshotlens.com/v1/screenshots" \ --data-urlencode "url=https://example.com" \ --data-urlencode "api_key=YOUR_API_KEY" \ --data-urlencode "response_type=json" ``` ```json { "screenshot_url": "https://cdn.screenshotlens.com/captures/example.png", "credits_charged": 1 } ``` ### Try a rolling video Rolling video records the page as it scrolls, and returns an MP4 by default. ```bash curl -G "https://api.screenshotlens.com/v1/videos/rolling" \ --data-urlencode "url=https://example.com" \ --data-urlencode "api_key=YOUR_API_KEY" \ --data-urlencode "response_type=json" ``` ```json { "video_url": "https://cdn.screenshotlens.com/captures/example.mp4", "credits_charged": 5 } ``` ### Move the request into your app Keep the API key on your server. Production keys do not belong in browser JavaScript, mobile apps, public repositories, or client-side build artifacts. ## Next steps * [Screenshot API](https://docs.screenshotlens.com/docs/api/screenshots) and [Rolling Video API](https://docs.screenshotlens.com/docs/api/rolling-video) list every parameter, default, and limit. * [Responses and Errors](https://docs.screenshotlens.com/docs/api/responses-errors) covers status codes and retry behavior. * [Authentication](https://docs.screenshotlens.com/docs/api/authentication) explains how to rotate and scope keys. # API Reference Source: https://docs.screenshotlens.com/docs/api Summary: The two ScreenshotLens capture endpoints, how they are authorized, and how their responses and errors are shaped. The public API is two capture endpoints plus a small set of key-management routes. Both capture endpoints are `GET` requests, take their parameters in the query string, and return either the media itself or a JSON body pointing at the stored asset. ## Endpoints | Endpoint | Captures | Cost | Reference | | ------------------------ | -------------------------------------------------------------- | ------------------------- | -------------------------------------------- | | `GET /v1/screenshots` | A viewport screenshot, or the whole page with `full_page=true` | 1 credit, 2 for full page | [Screenshot API](https://docs.screenshotlens.com/docs/api/screenshots) | | `GET /v1/videos/rolling` | An MP4 or GIF of the page scrolling, up to 30 seconds | 5 credits | [Rolling Video API](https://docs.screenshotlens.com/docs/api/rolling-video) | Base URL: `https://api.screenshotlens.com` ## What every capture request shares * `url` is required, must be absolute, and must use `http` or `https`. * `api_key` authorizes the request unless it carries a dashboard session. See [Authentication](https://docs.screenshotlens.com/docs/api/authentication). * `response_type` is `binary` by default and `json` while you are integrating. * Viewports run from 1×1 up to 7680×4320, and `wait_until` picks the lifecycle event to capture on. * Ad and cookie-banner blocking are on by default and can be turned off per request. ## Reading the result [Responses and Errors](https://docs.screenshotlens.com/docs/api/responses-errors) covers the success bodies, the five status codes the API returns, and the difference between an API failure and a target page that itself answered an error. Two rules are worth knowing up front: * A capture that fails costs zero credits. * A `402` means the wallet cannot cover the request, so retrying will not clear it. ## In this section * [Authentication](https://docs.screenshotlens.com/docs/api/authentication): passing an API key, the key-management routes, and key hygiene * [Screenshot API](https://docs.screenshotlens.com/docs/api/screenshots): every parameter, default, and limit for still captures * [Rolling Video API](https://docs.screenshotlens.com/docs/api/rolling-video): recording, scroll timing, and output formats * [Responses and Errors](https://docs.screenshotlens.com/docs/api/responses-errors): status codes, error bodies, and idempotency # Authentication Source: https://docs.screenshotlens.com/docs/api/authentication Summary: Authorize capture requests with API keys created in the dashboard. ## Authorize a request Pass the key as the `api_key` query parameter. ```bash curl -G "https://api.screenshotlens.com/v1/screenshots" \ --data-urlencode "url=https://example.com" \ --data-urlencode "api_key=YOUR_API_KEY" \ --data-urlencode "response_type=json" ``` A missing or invalid key returns `401 Unauthorized` with an empty body. Requests made from a signed-in dashboard session are authorized by the session cookie, so the Playground works without a key. ## Manage keys Create, rename, and revoke keys under **API keys** at [app.screenshotlens.com](https://app.screenshotlens.com). The dashboard calls these endpoints, which require a session rather than an API key: | Method | Path | Purpose | | -------- | ------------------- | ------------ | | `GET` | `/v1/api-keys` | List keys | | `POST` | `/v1/api-keys` | Create a key | | `PUT` | `/v1/api-keys/{id}` | Rename a key | | `DELETE` | `/v1/api-keys/{id}` | Revoke a key | ## Key hygiene * Use separate keys for production, staging, CI, and internal tools. * Rotate a key when ownership changes or when it may have been exposed. * Store production keys in server-side environment variables or a secret manager. * Never ship a production key in frontend code. [API Keys](https://docs.screenshotlens.com/docs/dashboard/api-keys) walks through creating and rotating keys in the dashboard. # Screenshot API Source: https://docs.screenshotlens.com/docs/api/screenshots Summary: Capture a still image of a public page as binary output or a JSON asset URL. ```http GET /v1/screenshots ``` The target `url` must be absolute and use `http` or `https`. ## Basic request **cURL** ```bash curl -G "https://api.screenshotlens.com/v1/screenshots" \ --data-urlencode "url=https://example.com" \ --data-urlencode "api_key=YOUR_API_KEY" \ --data-urlencode "response_type=json" ``` **JavaScript** ```ts const params = new URLSearchParams({ url: "https://example.com", api_key: process.env.SCREENSHOTLENS_API_KEY!, response_type: "json", }) const response = await fetch( `https://api.screenshotlens.com/v1/screenshots?${params}`, ) const capture = await response.json() ``` ## Common parameters | Parameter | Type | Default | Limits | | ---------------------- | ------------------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `url` | absolute URL | none | Required. Must use `http` or `https`. | | `api_key` | string | none | Required unless the request carries a dashboard session. | | `response_type` | `binary` or `json` | `binary` | Use `json` while integrating. | | `viewport_device` | string | none | A Playwright device name, e.g. `iPhone 13` or `Pixel 5`. Emulates that device's viewport, scale factor, user agent, and touch support, overriding `viewport_width`, `viewport_height`, and `scale_factor`. | | `viewport_width` | integer | `1280` | `1` to `7680` pixels | | `viewport_height` | integer | `720` | `1` to `4320` pixels | | `scale_factor` | integer | `1` | `1` to `5` | | `delay` | integer | `0` | `0` to `10` seconds, waited before capture | | `timeout` | integer | `30` | `0` to `30` seconds | | `wait_until` | enum | `Load` | `Load`, `DomContentLoaded`, `NetworkIdle0`, `NetworkIdle2` | | `dark` | boolean | `false` | Emulates a dark color scheme | | `block_ads` | boolean | `true` | Blocks common ad resources | | `block_cookie_banners` | boolean | `true` | Blocks and dismisses common cookie banners | | `block_chat` | boolean | `false` | Blocks common chat widgets | ## Image parameters | Parameter | Type | Default | Limits | | --------------- | ------- | ------- | ----------------------------------------------- | | `image_format` | enum | `Png` | `Png`, `Jpeg`, `Webp` | | `image_quality` | integer | `80` | `0` to `100`, applied to `Jpeg` and `Webp` only | ## Full-page parameters | Parameter | Type | Default | Limits | | -------------- | ------- | ------- | ---------------------------------------------------------------------- | | `full_page` | boolean | `false` | Captures the whole page instead of the viewport | | `scroll` | boolean | `false` | Scrolls before capture to trigger lazy content, needs `full_page=true` | | `scroll_delay` | integer | `200` | `0` to `5000` milliseconds between scroll steps | | `scroll_by` | integer | `500` | `100` to `10000` pixels per scroll step | | `max_height` | integer | none | `1` to `50000` pixels, caps a tall page | ## Response modes ### JSON `response_type=json` returns the stored asset URL. ```json { "screenshot_url": "https://cdn.screenshotlens.com/captures/example.png", "credits_charged": 1 } ``` ### Binary The default `response_type=binary` returns the image file itself, with `Content-Type` set from `image_format`. ```bash curl -G "https://api.screenshotlens.com/v1/screenshots" \ --data-urlencode "url=https://example.com" \ --data-urlencode "api_key=YOUR_API_KEY" \ --output capture.png ``` When ScreenshotLens can read the target page status, the binary response carries it in `X-Page-Status-Code`. ## Pricing A viewport screenshot costs 1 credit and a full-page screenshot costs 2. See [Credits and Billing](https://docs.screenshotlens.com/docs/dashboard/credits-billing) for when the charge lands and when it does not. # Rolling Video API Source: https://docs.screenshotlens.com/docs/api/rolling-video Summary: Record a public page as it scrolls, and get back an MP4 or a GIF. ```http GET /v1/videos/rolling ``` The target `url` must be absolute and use `http` or `https`. ## Basic request **cURL** ```bash curl -G "https://api.screenshotlens.com/v1/videos/rolling" \ --data-urlencode "url=https://example.com" \ --data-urlencode "api_key=YOUR_API_KEY" \ --data-urlencode "response_type=json" ``` **JavaScript** ```ts const params = new URLSearchParams({ url: "https://example.com", api_key: process.env.SCREENSHOTLENS_API_KEY!, response_type: "json", }) const response = await fetch( `https://api.screenshotlens.com/v1/videos/rolling?${params}`, ) const capture = await response.json() ``` ## Parameters | Parameter | Type | Default | Limits | | ---------------------- | ------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `url` | absolute URL | none | Required. Must use `http` or `https`. | | `api_key` | string | none | Required unless the request carries a dashboard session. | | `response_type` | `binary` or `json` | `binary` | Use `json` while integrating. | | `format` | enum | `Mp4` | `Mp4`, `Gif` | | `duration` | integer | `5` | `1` to `30` seconds of recording | | `viewport_device` | string | none | A Playwright device name, e.g. `iPhone 13` or `Pixel 5`. Emulates that device's viewport, user agent, and touch support, overriding `viewport_width` and `viewport_height`. | | `viewport_width` | integer | `1280` | `1` to `7680` pixels | | `viewport_height` | integer | `720` | `1` to `4320` pixels | | `delay` | integer | `0` | `0` to `10` seconds, waited before recording | | `timeout` | integer | `30` | `0` to `30` seconds | | `start_delay` | integer | `0` | `0` to `10000` milliseconds of still frames before the first scroll | | `scroll_delay` | integer | `500` | `0` to `5000` milliseconds paused between scroll steps | | `one_scroll_duration` | integer | `1500` | `100` to `5000` milliseconds for a single scroll step | | `scroll_by` | integer | `1000` | `100` to `5000` pixels per scroll step | | `wait_until` | enum | `Load` | `Load`, `DomContentLoaded`, `NetworkIdle0`, `NetworkIdle2` | | `dark` | boolean | `false` | Emulates a dark color scheme | | `block_ads` | boolean | `true` | Blocks common ad resources | | `block_cookie_banners` | boolean | `true` | Blocks and dismisses common cookie banners | | `block_chat` | boolean | `false` | Blocks common chat widgets | ## Response modes ### JSON `response_type=json` returns the stored asset URL. ```json { "video_url": "https://cdn.screenshotlens.com/captures/example.mp4", "credits_charged": 5 } ``` ### Binary The default `response_type=binary` redirects to the stored media URL, so pass `-L` to follow it. ```bash curl -L -G "https://api.screenshotlens.com/v1/videos/rolling" \ --data-urlencode "url=https://example.com" \ --data-urlencode "api_key=YOUR_API_KEY" \ --output capture.mp4 ``` ## Pricing Rolling video costs 5 credits in both formats and at any duration. See [Credits and Billing](https://docs.screenshotlens.com/docs/dashboard/credits-billing) for when the charge lands and when it does not. # Responses and Errors Source: https://docs.screenshotlens.com/docs/api/responses-errors Summary: Status codes, error bodies, and what to do about each one. ## Success responses | Endpoint | `response_type=json` | `response_type=binary` | | -------------------- | ----------------------------------- | ---------------------------------- | | `/v1/screenshots` | `screenshot_url`, `credits_charged` | The image file | | `/v1/videos/rolling` | `video_url`, `credits_charged` | A redirect to the stored media URL | Screenshot binary responses also carry `X-Page-Status-Code` when ScreenshotLens can read the target page status. ## Status codes | Status | Meaning | What to do | | ------ | ---------------------------------- | ----------------------------------------------------------- | | `200` | The capture completed. | Read the file or the JSON body. | | `400` | Validation failed. | Fix the query string. | | `401` | Missing or invalid authentication. | Check `api_key`. | | `402` | Not enough credits. | Add credits or send a cheaper request. | | `500` | The render or the platform failed. | Retry, then check [Usage Logs](https://docs.screenshotlens.com/docs/dashboard/usage-logs). | ## Validation errors A `400` response names the problem in an `error` field. ```json { "error": "url must be a valid http or https URL" } ``` Most validation failures come from a missing `url`, a `response_type` other than `binary` or `json`, an unrecognized enum value, or a viewport or timing value outside the limits listed on the [Screenshot API](https://docs.screenshotlens.com/docs/api/screenshots) and [Rolling Video API](https://docs.screenshotlens.com/docs/api/rolling-video) pages. ## Credit errors When the wallet balance cannot cover the request, nothing is rendered and the API returns `402 Payment Required` with the shortfall. ```json { "error": "insufficient_credits", "balance": 3, "required": 5, "breakdown": [ { "feature": "base", "cost": 5, "description": "video_rolling" } ] } ``` A `402` is an account state, not a transient failure, so retrying the same request will not clear it. ## Target page errors ScreenshotLens records the target page status separately from the API response status. A page that answers `404` still produces a `200` capture of whatever it rendered, and that capture is free. [Usage Logs](https://docs.screenshotlens.com/docs/dashboard/usage-logs) shows both statuses side by side. ## Idempotency Capture endpoints accept an optional `Idempotency-Key` header. Without it, every request gets its own generated key, so a client that retries after a network interruption is charged twice for what it sees as one capture. Send your own key when a retry should settle as a single charge. # Dashboard Source: https://docs.screenshotlens.com/docs/dashboard Summary: Build requests in the Playground, manage API keys, read usage logs, and buy credits at app.screenshotlens.com. The dashboard at [app.screenshotlens.com](https://app.screenshotlens.com) is where you get a key, try a request, and see what each request cost. It calls the same API your server will, so anything that works there works from code. ## In this section | Page | Use it to | | ------------------------------------------------------ | -------------------------------------------------------------------------------------- | | [Playground](https://docs.screenshotlens.com/docs/dashboard/playground) | Build a capture request in the browser, preview the result, and copy the generated URL | | [API Keys](https://docs.screenshotlens.com/docs/dashboard/api-keys) | Create, name, rotate, and revoke the keys your integration uses | | [Usage Logs](https://docs.screenshotlens.com/docs/dashboard/usage-logs) | Inspect request history, statuses, timings, stored assets, and credits charged | | [Credits and Billing](https://docs.screenshotlens.com/docs/dashboard/credits-billing) | See credit costs, buy packages, and manage billing | ## The usual order 1. Create a key under **API keys**, named after the system that will use it. 2. Build the request in the **Playground** with `response_type=json` and check the credit cost before running it. 3. Copy the generated URL into your server code and swap in the key from your secret manager. 4. Check **Usage logs** when a request behaves differently in production than it did in the Playground. New accounts start with 100 credits, so every step above works before you buy anything. # Playground Source: https://docs.screenshotlens.com/docs/dashboard/playground Summary: Build and test a capture request in the dashboard before putting it in code. The Playground at [app.screenshotlens.com](https://app.screenshotlens.com) sends the same requests as the public API, so anything that works there works from your server. Use it to switch between screenshot and rolling video, set viewport, timing, output, blocking, and dark mode options, preview the result, check the credit cost before running, and copy the generated API URL. ## Recommended flow 1. Start with `response_type=json`. 2. Capture the page with the defaults. 3. Change one option at a time when the output is not stable enough. 4. Copy the generated URL into your server-side integration. 5. Check [Usage Logs](https://docs.screenshotlens.com/docs/dashboard/usage-logs) after the first production request. ## When to tune parameters | Problem | Option to try first | | --------------------------------------------------- | ----------------------------------------------------------------------------- | | The capture fires before the content renders | Raise `delay`, or set `wait_until=NetworkIdle0` | | Lazy content is missing from a full-page screenshot | Set `scroll=true` alongside `full_page=true` | | Sticky overlays cover the content | Keep `block_cookie_banners=true` and set `block_chat=true` | | The render needs the dark theme | Set `dark=true` | | The page is too tall to be useful | Cap it with `max_height` | | The request times out | Lower the capture complexity, or raise `timeout` toward its 30 second ceiling | For exact names and limits, see the [Screenshot API](https://docs.screenshotlens.com/docs/api/screenshots) and [Rolling Video API](https://docs.screenshotlens.com/docs/api/rolling-video). # API Keys Source: https://docs.screenshotlens.com/docs/dashboard/api-keys Summary: Create, name, rotate, and revoke the keys your integration uses. ## Create a key Open **API keys** at [app.screenshotlens.com](https://app.screenshotlens.com) and create a key named after the system that will use it, such as `Production`, `Staging`, `CI`, or `Internal previews`. Store it in your server environment or secret manager as soon as it is created. ## Rotate a key 1. Create a replacement key. 2. Deploy it to your application. 3. Confirm the new requests appear in [Usage Logs](https://docs.screenshotlens.com/docs/dashboard/usage-logs). 4. Revoke the old key. ## Keep keys safe * Keep production keys out of browser code and out of source control. * Revoke any key that has been exposed or no longer has an owner. * Give each system its own key, so the logs stay readable. [Authentication](https://docs.screenshotlens.com/docs/api/authentication) covers how a key authorizes a request. # Usage Logs Source: https://docs.screenshotlens.com/docs/dashboard/usage-logs Summary: Inspect request history, statuses, timings, assets, and credits. Open **Usage logs** at [app.screenshotlens.com](https://app.screenshotlens.com) to see every request made with your account, newest first. ## What a log entry holds Each entry records the request (operation code, endpoint, request ID, parameters, and target host), the outcome (API response status, target page status, start and completion timestamps, duration, error code and message), the billing result (credits charged and whether the request was free), and the stored asset (resource URL, size, and content type). ## Common checks | Question | Where to look | | ------------------------------ | ------------------------------------------------- | | Did the API reject my request? | API response status and error message | | Did the target page fail? | Target page status | | Was I charged? | Credits charged and the free flag | | Which page did I capture? | Request host and request parameters | | Did the render take too long? | Duration, against the `timeout` in the parameters | ## Reading logs from the API ```http GET /v1/api-usage-logs?page=1&pageSize=10 ``` This endpoint needs a dashboard session rather than an API key. It returns `items`, `totalCount`, `page`, and `pageSize`, and it clamps out-of-range paging instead of rejecting it: | Input | Result | | ---------------- | -------------- | | `page < 1` | `page=1` | | `pageSize < 1` | `pageSize=10` | | `pageSize > 100` | `pageSize=100` | Pair the logs with [Responses and Errors](https://docs.screenshotlens.com/docs/api/responses-errors) when you are tracking down production behavior. # Credits and Billing Source: https://docs.screenshotlens.com/docs/dashboard/credits-billing Summary: How credit pricing, charging, and billing actions work. ScreenshotLens runs on prepaid credits. New accounts start with 100. ## Credit costs | Capture | Cost | | -------------------- | --------- | | Viewport screenshot | 1 credit | | Full-page screenshot | 2 credits | | Rolling video | 5 credits | Rolling video costs the same in both formats and at any duration. ## When credits move The balance is checked before the render starts. If it cannot cover the request, the API returns `402 Payment Required` and nothing is rendered, so a request you cannot afford never costs you anything. The charge lands after a successful capture. One case is free: if the target page answers with a status of `400` or higher, you still get the capture and the response reports `credits_charged` as `0`. ## Billing actions Open **Billing** at [app.screenshotlens.com](https://app.screenshotlens.com) to check your balance, review the credit ledger, buy credits, inspect usage trends, and open the payment portal. ## Related API endpoints These endpoints back the Billing page. All of them need a dashboard session rather than an API key, except `/v1/packages`, which is public. | Method | Path | Purpose | | ------ | ---------------------------- | ------------------------- | | `GET` | `/v1/credits/balance` | Current wallet balance | | `GET` | `/v1/credits/transactions` | Credit ledger history | | `GET` | `/v1/credits/chart` | Balance chart data | | `POST` | `/v1/credits/buy` | Start checkout | | `POST` | `/v1/credits/manage-billing` | Open the payment portal | | `GET` | `/v1/packages` | Available credit packages | [Responses and Errors](https://docs.screenshotlens.com/docs/api/responses-errors) shows the full `402` body.