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

# Rate limits

> Understanding API rate limits and quotas

LinkXG applies rate limits to protect the platform and ensure fair usage. This guide explains how limits work and how to handle them in your integration.

## Types of limits

LinkXG enforces three types of limits:

| Type                  | Description               | Example                      |
| --------------------- | ------------------------- | ---------------------------- |
| **Rate limits**       | Requests per time window  | 1,000 API requests per day   |
| **Resource limits**   | Maximum counts of objects | 1,000 active products        |
| **Capability limits** | Feature availability      | Bulk upload enabled/disabled |

Limits vary by subscription tier. Higher tiers have higher limits.

***

## Rate limits by tier

### API requests

| Tier          | Requests per day | Requests per minute |
| ------------- | ---------------- | ------------------- |
| Supplier Free | Not available    | —                   |
| Supplier Plus | 10,000           | 100                 |
| Core          | 50,000           | 500                 |
| Enterprise    | 200,000          | 2,000               |

### Authentication endpoints

Authentication endpoints have separate, stricter limits to prevent abuse:

| Endpoint        | Limit                             |
| --------------- | --------------------------------- |
| `/auth/login`   | 10 requests per minute per IP     |
| `/auth/refresh` | 30 requests per minute per token  |
| `/oauth/token`  | 60 requests per minute per client |

***

## Resource limits by tier

| Resource                    | Supplier Free | Supplier Plus | Core      | Enterprise |
| --------------------------- | ------------- | ------------- | --------- | ---------- |
| Active products             | 1,000         | 5,000         | Unlimited | Unlimited  |
| Connections                 | 3             | 15            | Unlimited | Unlimited  |
| Users                       | 3             | 10            | 25        | Unlimited  |
| Products under traceability | —             | —             | 10,000    | Unlimited  |
| Bulk upload rows/month      | 1,000         | 10,000        | 100,000   | Unlimited  |

***

## Checking your usage

### Via API

```bash theme={null}
curl https://api.linkxg.com/api/v1/entitlements/usage \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

**Response:**

```json theme={null}
{
  "success": true,
  "data": {
    "tier": {
      "code": "CORE",
      "name": "LinkXG Core"
    },
    "limits": {
      "MAX_ACTIVE_PRODUCTS": {
        "current": 847,
        "limit": null,
        "unlimited": true
      },
      "MAX_CONNECTIONS": {
        "current": 12,
        "limit": null,
        "unlimited": true
      }
    },
    "rateLimits": {
      "API_REQUESTS_DAY": {
        "current": 4521,
        "limit": 50000,
        "resetsAt": "2026-01-22T00:00:00.000Z"
      }
    },
    "warnings": []
  }
}
```

### Via application

Go to **Account > Usage** to see your current usage and limits in the application.

***

## Rate limit headers

API responses include headers showing your rate limit status:

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

**Example headers:**

```
X-RateLimit-Limit: 50000
X-RateLimit-Remaining: 45479
X-RateLimit-Reset: 1737504000
```

***

## Handling rate limits

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

```json theme={null}
{
  "error": "RATE_LIMIT_EXCEEDED",
  "message": "API request limit exceeded",
  "retryAfter": 3600
}
```

The `Retry-After` header indicates how many seconds to wait before retrying.

### Best practices

**Implement exponential backoff.** When you receive a 429, wait before retrying. Double the wait time on each subsequent 429.

```javascript theme={null}
async function requestWithBackoff(url, options, maxRetries = 5) {
  let delay = 1000;
  
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, options);
    
    if (response.status !== 429) {
      return response;
    }
    
    const retryAfter = response.headers.get('Retry-After');
    const waitTime = retryAfter ? parseInt(retryAfter) * 1000 : delay;
    
    await new Promise(resolve => setTimeout(resolve, waitTime));
    delay *= 2;
  }
  
  throw new Error('Max retries exceeded');
}
```

**Cache responses where appropriate.** If data does not change frequently, cache it locally rather than requesting it repeatedly.

**Use pagination efficiently.** Request only the data you need. Use smaller page sizes for exploratory queries.

**Batch requests where possible.** Some endpoints accept batch operations that count as a single request.

***

## Checking permissions before acting

Before attempting an action, you can check whether your current tier allows it:

```bash theme={null}
curl -X POST https://api.linkxg.com/api/v1/entitlements/can \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "BULK_UPLOAD",
    "resourceCount": 5000
  }'
```

**Response:**

```json theme={null}
{
  "success": true,
  "data": {
    "allowed": true,
    "reason": null
  }
}
```

If the action is not allowed:

```json theme={null}
{
  "success": true,
  "data": {
    "allowed": false,
    "reason": "LIMIT_EXCEEDED",
    "details": {
      "limit": "BULK_UPLOAD_ROWS_MONTH",
      "current": 9500,
      "requested": 5000,
      "available": 500
    }
  }
}
```

***

## Upgrade context

When a user reaches for a capability their tier does not include, you can resolve the contextual upgrade card to render at the point of friction — the headline, feature highlights, the current tier, the tier that unlocks the capability, and a call to action. Pass the capability key as the `capability` query parameter.

```bash theme={null}
curl "https://api.linkxg.com/api/v1/entitlements/upgrade-context?capability=EXPECTED_DATA_SETS" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

**Response:**

```json theme={null}
{
  "success": true,
  "data": {
    "capability": "EXPECTED_DATA_SETS",
    "frictionType": "CAPABILITY",
    "upgradeAvailable": true,
    "currentTier": { "code": "SUPPLIER_FREE", "name": "Supplier Free" },
    "targetTier": { "code": "LINKXG_CORE", "name": "LinkXG Core" },
    "headline": "Define what you need from suppliers",
    "featureHighlights": [
      "Build Expected Data Sets keyed to compliance regimes",
      "Generate data requests directly from gaps"
    ],
    "cta": "Upgrade to LinkXG Core"
  }
}
```

`frictionType` is `CAPABILITY` (the feature is not in the tier), `LIMIT` (a resource ceiling was reached), or `RATE_LIMIT` (a request ceiling was reached). When no upgrade unlocks the capability, `upgradeAvailable` is `false` and `targetTier` is omitted.

***

## Upgrading your limits

If you consistently hit limits, consider upgrading your subscription tier. Go to **Account > Subscription** or contact sales for enterprise options.

For temporary increases (e.g., a large data migration), contact support to discuss a temporary override.

***

## Next steps

<CardGroup cols={2}>
  <Card title="Error handling" icon="triangle-exclamation" href="/developers/errors">
    Understand error responses and handling
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference">
    Browse the complete API documentation
  </Card>
</CardGroup>
