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

# Batch capture

> POST /v1/capture/batch — capture screenshots of multiple URLs in a single request.

## Endpoint

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

Capture up to 50 URLs in a single request. Each URL is processed as a separate screenshot job using a background queue.

## Headers

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

## Request body

<ParamField body="urls" type="array" required>
  Array of URLs to capture (1–50 URLs). Each must be a valid URL.
</ParamField>

<ParamField body="options" type="object">
  Shared capture options applied to all URLs. Accepts the same options as the [capture endpoint](/api-reference/capture-screenshot) (e.g., `format`, `viewport_width`, `full_page`).
</ParamField>

## Response

### 201 Created

```json theme={null}
{
  "success": true,
  "data": [
    {
      "_id": "67b8a1c2d3e4f5a6b7c8d9e0",
      "url": "https://example.com",
      "status": "pending",
      "createdAt": "2025-05-14T10:00:00.000Z"
    },
    {
      "_id": "67b8a1c2d3e4f5a6b7c8d9e1",
      "url": "https://example.org",
      "status": "pending",
      "createdAt": "2025-05-14T10:00:00.000Z"
    }
  ],
  "count": 2,
  "succeededCount": 2,
  "failedCount": 0,
  "remainingCredits": 4998
}
```

### Response fields

<ResponseField name="data" type="array">
  Array of screenshot records, one per URL.
</ResponseField>

<ResponseField name="count" type="number">
  Total number of URLs in the batch.
</ResponseField>

<ResponseField name="succeededCount" type="number">
  Number of screenshots successfully queued.
</ResponseField>

<ResponseField name="failedCount" type="number">
  Number of screenshots that failed to queue. Credits for failed captures are refunded automatically.
</ResponseField>

<ResponseField name="remainingCredits" type="number">
  Your remaining monthly screenshot credits after this batch.
</ResponseField>

### Error responses

| Status | Code                                  | Description                                   |
| ------ | ------------------------------------- | --------------------------------------------- |
| 401    | `missing_api_key` / `invalid_api_key` | Invalid or missing API key                    |
| 402    | `usage_limit_exceeded`                | Not enough remaining credits for this batch   |
| 422    | `invalid_options`                     | Validation failed — check the `details` field |

<Note>
  The API validates that you have enough monthly credits for the entire batch before processing. If you have 10 credits remaining and submit 15 URLs, the entire request will be rejected.
</Note>

## Examples

### Basic batch capture

```bash theme={null}
curl -X POST https://api.screenshotly.dev/v1/capture/batch \
  -H "X-API-Key: $SCREENSHOTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": [
      "https://example.com",
      "https://example.org",
      "https://example.net"
    ]
  }'
```

### Batch with shared options

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

### Polling for batch results

After submitting a batch, poll individual screenshot IDs to track completion:

```javascript theme={null}
const response = await fetch('https://api.screenshotly.dev/v1/capture/batch', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.SCREENSHOTLY_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    urls: ['https://example.com', 'https://example.org'],
    options: { format: 'png' },
  }),
});

const { data: screenshots } = await response.json();

// Poll each screenshot for completion
for (const screenshot of screenshots) {
  const status = await fetch(
    `https://api.screenshotly.dev/v1/screenshots/${screenshot._id}/status`,
    { headers: { 'X-API-Key': process.env.SCREENSHOTLY_API_KEY } }
  );
  const result = await status.json();
  console.log(`${screenshot.url}: ${result.data.status}`);
}
```
