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

# Rate Limits

> Request quotas and rate limits for the Nexus API

Nexus enforces a monthly request quota and a per-second rate limit on every API key. Both depend on your plan.

## Limits by plan

| Plan           | Requests / mo | Rate limit | Burst | API keys  |
| -------------- | ------------- | ---------- | ----- | --------- |
| **Builder**    | 2M            | 25 req/s   | 250   | 3         |
| **Growth**     | 10M           | 50 req/s   | 500   | 5         |
| **Scale**      | 50M           | 100 req/s  | 1,000 | 10        |
| **Enterprise** | 200M          | 500 req/s  | 5,000 | Unlimited |

<Info>
  **Burst** is the token-bucket depth: the maximum number of requests you can fire in an instant before the per-second rate limit throttles you.
</Info>

### Without an active subscription

Requests authenticated against an expired, cancelled, or suspended subscription, and any request that can't be tied to an active plan, are degraded to a restrictive floor:

|               | Limit   |
| ------------- | ------- |
| Requests / mo | 10,000  |
| Rate limit    | 5 req/s |
| Burst         | 10      |

## Rate limit headers

Metered responses carry three headers describing your **monthly** quota:

| Header                  | Meaning                                                                            |
| ----------------------- | ---------------------------------------------------------------------------------- |
| `X-RateLimit-Limit`     | Your plan's monthly request quota                                                  |
| `X-RateLimit-Remaining` | Requests left this month (never below 0)                                           |
| `X-RateLimit-Reset`     | When the quota refills, as Unix epoch seconds - 00:00 UTC on the 1st of next month |

```http theme={null}
X-RateLimit-Limit: 2000000
X-RateLimit-Remaining: 1857201
X-RateLimit-Reset: 1782864000
```

<Info>
  These headers describe the **monthly quota only**. The per-second rate limit is not reported in headers - on a per-second 429, read `Retry-After` instead (see below).
</Info>

Scope and absence:

* The headers appear on **metered REST responses** - the blockchain data endpoints that count against your quota. Dashboard and account-management endpoints (auth, billing, `/api/user`, `/api/keys`) are not metered and don't carry them.
* They are **not** sent for MCP traffic (`/mcp/**` reports quota errors inside the JSON-RPC envelope) or on WebSocket streams.
* Plans with an unlimited request allowance (Enterprise arrangements without a monthly cap) get no `X-RateLimit-*` headers at all. **Absence is not an error** - it just means no monthly cap applies.

## When you hit a limit

Nexus returns **HTTP 429** with a JSON body. There are two cases, and you can tell them apart by their headers:

**Monthly quota exhausted** - the response carries the `X-RateLimit-*` headers (`X-RateLimit-Remaining: 0`), a `Retry-After` header with the seconds until your quota refills, and `reset_at` in the body (the same instant as `X-RateLimit-Reset`, as an ISO timestamp):

```http theme={null}
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 2000000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1782864000
Retry-After: 1728000
```

```json theme={null}
{
  "error": "rate_limit_exceeded",
  "message": "Monthly request limit reached. Upgrade at https://nexus.gerowallet.io/dashboard/billing/",
  "limit": 2000000,
  "reset_at": "2026-07-01T00:00:00Z"
}
```

**Per-second rate exceeded** - no `X-RateLimit-*` headers, just `Retry-After: 1`. Slow down and retry shortly:

```json theme={null}
{
  "error": "rate_limit_exceeded",
  "message": "Rate limit exceeded — slow down",
  "limit": 25
}
```

<Note>
  Branch on header presence: a 429 with `X-RateLimit-Reset` (or `reset_at` in the body) means your monthly quota is exhausted until the reset - don't retry in a loop. A 429 with only `Retry-After: 1` means you're sending too fast right now.
</Note>

<Info>
  Counters reset at **00:00 UTC on the 1st** of each month. The reset job runs at - or moments after - that instant, so a request fired exactly at the boundary can still see one final 429. Tolerate a single extra retry right at reset time rather than treating it as an error.
</Info>

### Add-on gating (402)

Endpoints behind a paid add-on (Market Data, Wallet Analytics, Transaction Builder) return **HTTP 402** when the add-on isn't active on your plan:

```json theme={null}
{
  "error": "payment_required",
  "addon": "marketData",
  "message": "Upgrade required at https://nexus.gerowallet.io/dashboard/billing/"
}
```

An account with **no active subscription** at all gets a 402 with a different `error` and no `addon`:

```json theme={null}
{
  "error": "subscription_required",
  "message": "An active subscription is required. Subscribe at https://nexus.gerowallet.io/dashboard/billing/"
}
```

## Handling 429s

Read `Retry-After` first - both 429 variants send it:

```javascript theme={null}
async function fetchWithBackoff(url, options, maxRetries = 4) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const response = await fetch(url, options);
    if (response.status !== 429) return response;

    // Monthly quota: don't hammer - surface to the caller.
    const body = await response.clone().json().catch(() => ({}));
    if (response.headers.get('X-RateLimit-Reset') || body.reset_at) {
      throw new Error(`Monthly quota reached, resets ${body.reset_at}`);
    }

    // Per-second: honor Retry-After, fall back to exponential backoff.
    const retryAfter = Number(response.headers.get('Retry-After'));
    const waitSeconds = retryAfter > 0 ? retryAfter : Math.pow(2, attempt);
    await new Promise((r) => setTimeout(r, waitSeconds * 1000));
  }
  throw new Error('Rate limited after retries');
}
```

## Best practices

<AccordionGroup>
  <Accordion title="Cache responses" icon="database">
    Cache frequently accessed, slow-changing data (block / tx / asset metadata) to cut request volume against your monthly quota.
  </Accordion>

  <Accordion title="Spread bursts" icon="gauge-high">
    Keep sustained throughput under your tier's per-second limit; the burst bucket absorbs short spikes, not steady overload.
  </Accordion>

  <Accordion title="Monitor usage" icon="chart-line">
    Watch `X-RateLimit-Remaining` on your responses so you can adjust before hitting the monthly cap.
  </Accordion>
</AccordionGroup>

## Upgrading

Need higher limits? Contact [nexus@gerowallet.io](mailto:nexus@gerowallet.io).

## Next steps

<CardGroup cols={2}>
  <Card title="Error Handling" icon="triangle-exclamation" href="/docs/concepts/error-handling">
    How Nexus reports API errors
  </Card>

  <Card title="Pagination" icon="list" href="/docs/concepts/pagination">
    Working with paginated responses
  </Card>
</CardGroup>
