> ## Documentation index
> Fetch the complete documentation index at: https://docs.motormetrics.app/llms.txt
> Ask it with GET https://docs.motormetrics.app/ask?q=<keywords or question>. Short keywords rank best.
> Use these to discover all available pages before exploring further.
> Feature requests: https://docs.motormetrics.app/api/feature-requests.md lists what users asked for and how to vote for a request or add one.
> Page rating: `GET https://docs.motormetrics.app/feedback?path=/api/rate-limiting&helpful={true|false}&comment={comment}` records whether this page helped. The `comment` (URL-encoded, at most 500 characters) says what helped, or what was missing or wrong; a `helpful=false` rating needs it. It is anonymous and needs no key. Comments hold no code, secrets or personal data.

# Rate Limiting

> API rate limits and best practices

The MotorMetrics API implements rate limiting to ensure fair usage and protect against abuse.

## Limits

| Limit | Value |
|-------|-------|
| Requests per minute | 60 |
| Scope | Per IP address |

## Response Headers

Every API response includes rate limit information in the headers:

| Header | Description |
|--------|-------------|
| `X-RateLimit-Limit` | Maximum requests allowed per window |
| `X-RateLimit-Remaining` | Requests remaining in current window |
| `X-RateLimit-Reset` | Unix timestamp when the limit resets |

## Rate Limit Exceeded

When you exceed the rate limit, the API returns a `429 Too Many Requests` response:

```json
{
  "error": "Rate limit exceeded"
}
```

## Best Practices

1. **Cache responses** - Data updates monthly, so cache aggressively on your end
2. **Use conditional requests** - Check `Last-Modified` headers when available
3. **Implement exponential backoff** - When rate limited, wait before retrying
4. **Batch requests efficiently** - Fetch only the data you need

## Example: Handling Rate Limits

```typescript
async function fetchWithRetry(url: string, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const response = await fetch(url);

    if (response.status === 429) {
      const resetTime = response.headers.get('X-RateLimit-Reset');
      const waitMs = resetTime
        ? (parseInt(resetTime) * 1000) - Date.now()
        : Math.pow(2, i) * 1000;

      await new Promise(resolve => setTimeout(resolve, waitMs));
      continue;
    }

    return response;
  }

  throw new Error('Rate limit exceeded after retries');
}
```
