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

# Screenshot

> Render a full-page screenshot of any URL as PNG, WebP, or JPEG.

Captures a full-page screenshot with headless Chromium: navigates to the URL, waits for the network to settle, scrolls to trigger lazy-loaded content and reveal animations, then encodes the result. The finished image is written to temporary storage and its filename returned — fetch the actual bytes from the download path described below.

<Info>
  **2 credits** per call · Typical response time \~310ms
</Info>

## Body parameters

<ParamField body="url" type="string" required>
  The page to capture. `https://` is assumed if the scheme is omitted.
</ParamField>

<ParamField body="format" default="png" type="string">
  Output image format: `png`, `jpeg`, or `webp`.
</ParamField>

<ParamField body="device" default="desktop" type="string">
  Viewport to render at: `desktop` or `mobile`.
</ParamField>

<ParamField body="colorScheme" default="light" type="string">
  Emulated `prefers-color-scheme` while rendering: `light` or `dark`. Affects any site that themes off this media query.
</ParamField>

## Response

<ResponseField name="success" type="boolean" required />

<ResponseField name="filename" type="string" required>
  Name of the generated file. Download it from `/api/uploads/<filename>` on the same host — the file is temporary and removed after roughly 5 minutes.
</ResponseField>

<ResponseField name="sizeBytes" type="integer" required>
  Size of the encoded image.
</ResponseField>

<ResponseField name="format" type="string" required>
  Echoes the requested `format`.
</ResponseField>

<ResponseField name="fileExtension" type="string" required>
  File extension for the download (`jpg` for the `jpeg` format, otherwise matches `format`).
</ResponseField>

<ResponseField name="clipped" type="boolean" required>
  `true` if the page was taller than the capture cap and the image was clipped rather than capturing the full height.
</ResponseField>

<ResponseField name="durationMs" type="integer" required>
  Total server-side time for the capture.
</ResponseField>

### Response headers

In addition to the [standard headers](/rate-limits-and-credits#response-headers), this endpoint sends:

<ResponseField name="X-Screenshot-Cache" type="string">
  `HIT` if served from the short-lived result cache without touching Chrome, otherwise `MISS`.
</ResponseField>

<ResponseField name="X-Screenshot-Clipped" type="string">
  Mirrors `clipped` in the body.
</ResponseField>

<ResponseField name="Server-Timing" type="string">
  Per-stage breakdown (`queue`, `page`, `nav`, `net`, `scroll`, `settle`, `encode`, `total`, all in ms) — renders as a waterfall in your browser's devtools Network panel.
</ResponseField>

## Errors

| Status | Cause                                                                               |
| ------ | ----------------------------------------------------------------------------------- |
| `400`  | `url` missing, or `format` / `device` / `colorScheme` not one of the allowed values |
| `400`  | The target could not be reached or rendered (message describes why)                 |

See the full [error reference](/errors) for the platform-level codes (`401`, `402`, `429`) that apply to every endpoint.

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.pocketutils.com/v1/screenshot \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://example.com",
      "format": "png",
      "device": "desktop",
      "colorScheme": "light"
    }'
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch("https://api.pocketutils.com/v1/screenshot", {
    method: "POST",
    headers: {
      Authorization: "Bearer YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      url: "https://example.com",
      format: "png",
      device: "desktop",
      colorScheme: "light",
    }),
  });
  const { filename } = await res.json();
  const imageUrl = `https://api.pocketutils.com/api/uploads/${filename}`;
  ```

  ```python Python theme={null}
  import requests

  res = requests.post(
      "https://api.pocketutils.com/v1/screenshot",
      headers={"Authorization": "Bearer YOUR_API_KEY"},
      json={"url": "https://example.com", "format": "png", "device": "desktop"},
  )
  filename = res.json()["filename"]
  image_url = f"https://api.pocketutils.com/api/uploads/{filename}"
  ```
</RequestExample>

<ResponseExample>
  ```json Response theme={null}
  {
    "success": true,
    "filename": "a1b2c3d4e5f6a7b8.png",
    "sizeBytes": 284213,
    "format": "png",
    "fileExtension": "png",
    "clipped": false,
    "durationMs": 298
  }
  ```
</ResponseExample>


## Related topics

- [Introduction](/index.md)
- [Rate Limits & Credits](/rate-limits-and-credits.md)
- [Errors](/errors.md)
