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

# Capture screenshot

> Capture a screenshot of any webpage with customizable options.

## Endpoint

```
POST https://api.screenshotly.dev/v1/capture
GET  https://api.screenshotly.dev/v1/capture
```

The `POST` method accepts parameters in the request body. The `GET` method accepts all parameters as query strings and always returns a binary image.

## Headers

| Header         | Required   | Description        |
| -------------- | ---------- | ------------------ |
| `X-API-Key`    | Yes        | Your API key       |
| `Content-Type` | Yes (POST) | `application/json` |

## Request body (POST)

<ParamField body="url" type="string" required>
  The URL of the webpage to capture. Must be a valid URL.
</ParamField>

<ParamField body="name" type="string">
  Optional name for the screenshot (max 100 characters).
</ParamField>

### Capture options

Pass these inside the `options` object in the request body.

<ParamField body="options.format" type="string" default="png">
  Output format. Options: `png`, `jpeg`, `webp`, `pdf`.
</ParamField>

<ParamField body="options.viewport_width" type="integer" default="1280">
  Viewport width in pixels (100–5000).
</ParamField>

<ParamField body="options.viewport_height" type="integer" default="1024">
  Viewport height in pixels (100–5000).
</ParamField>

<ParamField body="options.full_page" type="boolean" default="false">
  Capture the full scrollable page instead of just the viewport.
</ParamField>

<ParamField body="options.image_quality" type="integer" default="80">
  Image quality for JPEG, WebP, and PDF (0–100). Ignored for PNG.
</ParamField>

<ParamField body="options.device_scale_factor" type="number" default="1">
  Device pixel ratio (1–3). Use `2` for retina-quality screenshots.
</ParamField>

<ParamField body="options.viewport_mobile" type="boolean" default="false">
  Emulate a mobile device viewport.
</ParamField>

<ParamField body="options.viewport_has_touch" type="boolean" default="false">
  Enable touch event support.
</ParamField>

<ParamField body="options.viewport_landscape" type="boolean" default="false">
  Use landscape orientation.
</ParamField>

<ParamField body="options.block_ads" type="boolean" default="false">
  Block advertisements on the page.
</ParamField>

<ParamField body="options.block_cookie_banners" type="boolean" default="false">
  Block cookie consent banners.
</ParamField>

<ParamField body="options.block_chats" type="boolean" default="false">
  Block chat widgets (e.g., Intercom, Drift).
</ParamField>

<ParamField body="options.selector" type="string">
  CSS selector of a specific element to capture instead of the full page (max 255 characters).
</ParamField>

<ParamField body="options.selector_scroll_into_view" type="boolean" default="true">
  Automatically scroll the selected element into view before capturing.
</ParamField>

<ParamField body="options.error_on_selector_not_found" type="boolean" default="false">
  Return an error if the specified selector is not found on the page.
</ParamField>

<ParamField body="options.wait_for_selector" type="string">
  CSS selector to wait for before capturing (max 255 characters). The capture starts once this element exists in the DOM.
</ParamField>

<ParamField body="options.delay" type="integer" default="0">
  Milliseconds to wait after page load before capturing (0–10000).
</ParamField>

<ParamField body="options.timeout" type="integer" default="60000">
  Maximum time in milliseconds to wait for the page and screenshot process (1000–90000).
</ParamField>

<ParamField body="options.navigation_timeout" type="integer" default="30000">
  Maximum time in milliseconds to wait for page navigation (1000–30000).
</ParamField>

<ParamField body="options.wait_until" type="string" default="load">
  When to consider navigation complete. Options: `load`, `domcontentloaded`, `networkidle0`, `networkidle2`. Can also be an array of values.
</ParamField>

<ParamField body="options.response_type" type="string" default="by_format">
  Controls the response format. Options: `by_format`, `json`, `empty`.
</ParamField>

<ParamField body="options.dark_mode" type="boolean">
  Emulate dark color scheme (`prefers-color-scheme: dark`).
</ParamField>

<ParamField body="options.omit_background" type="boolean" default="false">
  Remove the default white background for transparent captures (PNG and WebP only).
</ParamField>

<ParamField body="options.full_page_scroll" type="boolean">
  Scroll through the page before capturing. Useful for triggering lazy-loaded content.
</ParamField>

<ParamField body="options.full_page_scroll_delay" type="integer" default="400">
  Milliseconds to wait between scroll steps (0–5000).
</ParamField>

<ParamField body="options.full_page_scroll_by" type="integer">
  Number of pixels to scroll per step (0–5000).
</ParamField>

<ParamField body="options.full_page_max_height" type="integer">
  Maximum height in pixels for full-page captures (0–50000).
</ParamField>

## Response

The response format depends on the `response_type` option.

### `response_type: "by_format"` (default)

Returns the screenshot as binary data with the appropriate `Content-Type` header (e.g., `image/png`, `image/jpeg`, `application/pdf`).

For `POST` requests, a `Content-Disposition: attachment` header is also included.

### `response_type: "json"`

Returns `201 Created` with a JSON response:

```json theme={null}
{
  "success": true,
  "data": {
    "id": "67b8a1c2d3e4f5a6b7c8d9e0",
    "url": "https://example.com",
    "image_url": "https://cdn.screenshotly.dev/screenshots/67b8a1c2d3e4f5a6b7c8d9e0.png",
    "status": "completed",
    "metadata": {
      "file_size": 245760,
      "format": "png",
      "dimensions": {
        "width": 1280,
        "height": 1024
      }
    },
    "created_at": "2025-05-14T10:30:00.000Z"
  },
  "remaining_credits": 99
}
```

### `response_type: "empty"`

Returns `200 OK` with an empty body. Useful for fire-and-forget captures.

### Error responses

| Status | Code                   | Description                                   |
| ------ | ---------------------- | --------------------------------------------- |
| 401    | `missing_api_key`      | No API key provided                           |
| 401    | `invalid_api_key`      | Invalid or revoked API key                    |
| 402    | `usage_limit_exceeded` | Monthly screenshot limit reached              |
| 422    | `invalid_options`      | Validation failed — check the `details` field |
| 422    | `invalid_url`          | URL format is invalid                         |
| 422    | `selector_not_found`   | Specified CSS selector not found on page      |
| 429    | `rate_limit_exceeded`  | Too many requests per minute                  |
| 500    | `render_failed`        | Screenshot capture failed                     |
| 502    | `host_error`           | Could not reach the target URL                |
| 503    | `service_unavailable`  | Screenshot service is starting up             |
| 504    | `navigation_timeout`   | Page navigation timed out                     |

See [error codes](/api-reference/error-codes) for the full error response format.

## Examples

### Basic capture (binary response)

```bash theme={null}
curl -X POST https://api.screenshotly.dev/v1/capture \
  -H "X-API-Key: $SCREENSHOTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}' \
  --output screenshot.png
```

### GET request (binary response)

```bash theme={null}
curl "https://api.screenshotly.dev/v1/capture?url=https://example.com&api_key=$SCREENSHOTLY_API_KEY" \
  --output screenshot.png
```

### Full-page JPEG with custom viewport (JSON response)

```bash theme={null}
curl -X POST https://api.screenshotly.dev/v1/capture \
  -H "X-API-Key: $SCREENSHOTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "options": {
      "format": "jpeg",
      "image_quality": 85,
      "full_page": true,
      "viewport_width": 1440,
      "viewport_height": 900,
      "response_type": "json"
    }
  }'
```

### Mobile device with dark mode

```bash theme={null}
curl -X POST https://api.screenshotly.dev/v1/capture \
  -H "X-API-Key: $SCREENSHOTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "options": {
      "viewport_width": 390,
      "viewport_height": 844,
      "device_scale_factor": 3,
      "viewport_mobile": true,
      "dark_mode": true,
      "response_type": "json"
    }
  }'
```

### Capture specific element with ad blocking

```bash theme={null}
curl -X POST https://api.screenshotly.dev/v1/capture \
  -H "X-API-Key: $SCREENSHOTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "options": {
      "selector": "#main-content",
      "block_ads": true,
      "block_cookie_banners": true,
      "response_type": "json"
    }
  }'
```
