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

# Rate limits

> API rate limits by plan, handling 429 responses, and retry strategies.

Screenshotly enforces rate limits to ensure fair usage and service reliability.

## Limits by plan

| Plan         | Monthly screenshots | Storage | Rate limit  | Price    |
| ------------ | ------------------- | ------- | ----------- | -------- |
| **Free**     | 100                 | 500 MB  | 5 req/min   | Free     |
| **Starter**  | 5,000               | 5 GB    | 20 req/min  | \$29/mo  |
| **Pro**      | 25,000              | 15 GB   | 60 req/min  | \$79/mo  |
| **Business** | 75,000              | 50 GB   | 120 req/min | \$199/mo |

Rate limits are applied per API key within a 60-second sliding window. Check your current usage in the [dashboard](https://app.screenshotly.dev).

## Rate limit headers

Every API response includes headers to help you track your usage:

| Header                  | Description                                      |
| ----------------------- | ------------------------------------------------ |
| `X-RateLimit-Limit`     | Maximum requests per minute for your plan        |
| `X-RateLimit-Remaining` | Remaining requests in the current window         |
| `X-RateLimit-Reset`     | Unix timestamp when the rate limit window resets |

When you hit the rate limit, a `Retry-After` header is also included indicating how many seconds to wait.

## 429 Too Many Requests

When you exceed your per-minute rate limit, the API returns a `429` status code:

```json theme={null}
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Too many requests. Please try again later."
  }
}
```

## 402 Usage Limit Exceeded

When you exceed your monthly screenshot quota, the API returns a `402` status code:

```json theme={null}
{
  "error": {
    "code": "usage_limit_exceeded",
    "message": "Monthly screenshot limit reached. Please upgrade your subscription."
  }
}
```

## Checking your usage

Use the [usage endpoint](/api-reference/screenshot-usage) to check your remaining credits programmatically:

```bash theme={null}
curl https://api.screenshotly.dev/v1/screenshots/usage \
  -H "X-API-Key: $SCREENSHOTLY_API_KEY"
```

When using `response_type: "json"` for captures, the response includes a `remaining_credits` field.

## Handling rate limits

### Exponential backoff

When you receive a 429 response, wait before retrying:

```javascript theme={null}
async function captureWithBackoff(url, options) {
  const maxRetries = 5;

  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch('https://api.screenshotly.dev/v1/capture', {
      method: 'POST',
      headers: {
        'X-API-Key': process.env.SCREENSHOTLY_API_KEY,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ url, options }),
    });

    if (response.ok) return response;
    if (response.status !== 429) throw new Error(`HTTP ${response.status}`);

    const retryAfter = response.headers.get('Retry-After');
    const delay = retryAfter ? parseInt(retryAfter) * 1000 : Math.pow(2, attempt) * 1000;
    console.log(`Rate limited. Retrying in ${delay}ms...`);
    await new Promise(resolve => setTimeout(resolve, delay));
  }

  throw new Error('Rate limit retry attempts exhausted');
}
```

## Best practices

* **Monitor usage** — check the `X-RateLimit-Remaining` header or the [usage endpoint](/api-reference/screenshot-usage) before large operations
* **Stagger requests** — spread requests over time instead of sending them all at once
* **Use batch processing** — the [batch endpoint](/api-reference/batch-capture) processes up to 50 URLs per request
* **Respect `Retry-After`** — use the header value for optimal retry timing
* **Upgrade your plan** — if you consistently hit limits, consider upgrading at [pricing](https://screenshotly.dev/pricing)
* **Cache results** — store screenshot URLs and reuse them instead of recapturing the same pages
