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

# Rate Limits

> API rate limiting details and best practices.

## Limits

NextKS uses dual-level rate limiting — per API key and per organization — so a single runaway integration doesn't block others.

### Per API key

| Metric    | Value                    |
| --------- | ------------------------ |
| Burst     | 10 requests in 5 seconds |
| Sustained | \~2 requests/second      |

### Per organization (tenant)

| Metric    | Value                     |
| --------- | ------------------------- |
| Burst     | 50 requests in 10 seconds |
| Sustained | \~5 requests/second       |

### Other limits

| Limit                  | Value              |
| ---------------------- | ------------------ |
| Recipients per request | 50 email addresses |
| Message length         | 4000 characters    |

When a rate limit is exceeded, the API returns:

```json theme={null}
{
  "status": "error",
  "details": "Per-key rate limit exceeded (10 burst / 2 per second)"
}
```

**HTTP status**: `429 Too Many Requests`
**Header**: `Retry-After: 1`

The `details` message indicates which limit was hit (per-key or organization).

## Idempotency

To safely retry requests without sending duplicate notifications, include an `Idempotency-Key` header:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://app.nextks.com/api/notify \
    -H "X-API-Key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: deploy-v2.4.1-notify-20260213" \
    -d '{ ... }'
  ```

  ```typescript Node.js theme={null}
  const response = await fetch('https://app.nextks.com/api/notify', {
    method: 'POST',
    headers: {
      'X-API-Key': 'YOUR_API_KEY',
      'Content-Type': 'application/json',
      'Idempotency-Key': 'deploy-v2.4.1-notify-20260213',
    },
    body: JSON.stringify({ /* ... */ }),
  })
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://app.nextks.com/api/notify",
      headers={
          "X-API-Key": "YOUR_API_KEY",
          "Idempotency-Key": "deploy-v2.4.1-notify-20260213",
      },
      json={ ... },
  )
  ```
</CodeGroup>

* If the same key is sent within **24 hours**, the cached response is returned without re-processing
* Keys are scoped per organization — different orgs can use the same key without conflict
* Keys older than 24 hours are automatically cleaned up

## Best practices

* **Batch recipients** — Send to multiple users in a single request instead of making separate calls per user
* **Respect `Retry-After`** — Wait the indicated number of seconds before retrying
* **Use idempotency keys** — Include an `Idempotency-Key` header when retrying failed requests to prevent duplicates
* **Use callbacks** — For interactive notifications, use `callback_url` instead of polling the status endpoint repeatedly
* **Cache responses** — Status endpoint results can be cached for a few seconds to avoid unnecessary calls
