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

# Rate Limits

> Per-key rate limits, response headers, and retry guidance for the Arcus API.

## Overview

The Arcus API enforces rate limits per API key to ensure fair usage across all integrations. Limits are applied using a sliding-window bucket per key.

## Default limits

| Tier                      | Requests per minute | Requests per second (burst) |
| ------------------------- | ------------------- | --------------------------- |
| Test mode keys            | 60                  | 10                          |
| Live mode keys (standard) | 300                 | 50                          |
| Live mode keys (elevated) | 1,200               | 100                         |

Elevated limits are available on request for high-volume integrations. Contact support via the in-app Help button with your use case and expected volume.

## Rate limit headers

Every response includes these headers:

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

When you exceed the limit, the API returns `429 Too Many Requests` with an additional header:

| Header        | Description                     |
| ------------- | ------------------------------- |
| `Retry-After` | Seconds to wait before retrying |

## Handling rate limits

```bash theme={null}
HTTP/2 429
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1716422460
Retry-After: 12
Content-Type: application/json

{
  "error": "rate_limit_exceeded",
  "code": "rate_limit_exceeded",
  "type": "rate_limit",
  "hint": "Rate limit exceeded. Retry after 12 seconds.",
  "request_id": "req_01H..."
}
```

## SDK auto-retry

All SDKs handle 429 responses automatically using the `Retry-After` header:

<CodeGroup>
  ```javascript Node theme={null}
  const arcus = new Arcus({
    apiKey: process.env.ARCUS_API_KEY,
    entityId: process.env.ARCUS_ENTITY_ID,
    maxRetries: 3,   // default: 2
    timeout: 30000,  // ms; default: 30000
  });
  // SDK automatically waits Retry-After seconds before retrying 429s
  ```

  ```python Python theme={null}
  arcus = Arcus(
      api_key=os.environ['ARCUS_API_KEY'],
      entity_id=os.environ['ARCUS_ENTITY_ID'],
      max_retries=3,   # default: 2
      timeout=30,      # seconds; default: 30
  )
  ```

  ```go Go theme={null}
  client := arcus.NewClient(
      os.Getenv("ARCUS_API_KEY"),
      arcus.WithEntityID(os.Getenv("ARCUS_ENTITY_ID")),
      arcus.WithMaxRetries(3),
      arcus.WithTimeout(30 * time.Second),
  )
  ```
</CodeGroup>

## Best practices for high-volume integrations

1. **Bulk endpoints:** prefer batch operations (e.g. bulk product import) over individual creates in a loop
2. **Pagination:** use `limit=100` to minimize list requests
3. **Concurrency:** keep concurrent requests below 10 per key; spread load across multiple keys if needed
4. **Backpressure:** implement exponential backoff even for retries that are not rate-limit-related
5. **Webhooks over polling:** subscribe to webhook events instead of polling list endpoints; polling is the most common cause of rate limit exhaustion

## Idempotency and retries

Always include `Idempotency-Key` on POST/PATCH/DELETE requests before retrying. If you hit a 429 and retry without an idempotency key, you may create duplicate records after the window resets.
