# Rate Limits

Understanding and working with AVCodex MCP Server rate limits.

---

The AVCodex MCP Server enforces rate limits to keep usage fair and the platform stable. Limits scale with subscription tier.

## Rate limits by tier

| Tier | Requests/minute | MCP access |
|------|-----------------|------------|
| **FREE** | 0 | Not available |
| **BUILDER** | 30 | Full access |
| **STUDIO** | 60 | Full access |
| **STUDIO_PRO** | 120 | Full access |
| **ENTERPRISE** | Unlimited | Full access |

> **Note:** MCP server access requires a Builder plan or higher. Free tier users cannot use the MCP server.

## Rate limit headers

Every response includes rate limit information:

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

**Example response headers:**

```
HTTP/1.1 200 OK
X-RateLimit-Tier: BUILDER
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 25
X-RateLimit-Reset: 1704067260
```

## Handling rate limits (429 errors)

When you exceed your limit, the server returns `429 Too Many Requests`:

```json
{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded. Try again in 45 seconds.",
    "tier": "BUILDER",
    "limit": 30,
    "reset": 1704067260
  }
}
```

### Retry-After header

The `Retry-After` header tells you exactly when to retry:

```
HTTP/1.1 429 Too Many Requests
Retry-After: 45
X-RateLimit-Reset: 1704067260
```

### Implementing retry logic

**Basic exponential backoff:**

```javascript
async function callWithRetry(makeRequest, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await makeRequest();

    if (response.status === 429) {
      const retryAfter = response.headers.get('Retry-After') || 60;
      console.log(`Rate limited. Waiting ${retryAfter}s...`);
      await sleep(retryAfter * 1000);
      continue;
    }

    return response;
  }
  throw new Error('Max retries exceeded');
}
```

**Respecting Retry-After:**

```python
import time
import requests

def call_mcp(tool_name, args):
    response = requests.post(
        "https://app.avcodex.com/mcp",
        json={"method": "tools/call", "params": {"name": tool_name, "arguments": args}},
        headers={"Authorization": f"Bearer {token}"}
    )

    if response.status_code == 429:
        retry_after = int(response.headers.get('Retry-After', 60))
        print(f"Rate limited. Sleeping {retry_after}s...")
        time.sleep(retry_after)
        return call_mcp(tool_name, args)  # Retry

    return response.json()
```

## Best practices

### 1. Batch operations

Instead of calling tools one at a time, combine related operations:

```
# Inefficient: 10 separate calls
for agent in agents:
    update_agent(agent.id, {...})

# Better: Use bulk patterns where available,
# or space calls out to stay within limits.
```

### 2. Use caching

Cache responses that don't change frequently. Manufacturer spec metadata, agent definitions, and analytics roll-ups don't move minute-to-minute:

```javascript
const agentCache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes

async function getAgent(agentId) {
  const cached = agentCache.get(agentId);
  if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
    return cached.data;
  }

  const agent = await mcpCall('get_app', { appId: agentId });
  agentCache.set(agentId, { data: agent, timestamp: Date.now() });
  return agent;
}
```

### 3. Monitor your usage

Check remaining requests before large operations:

```javascript
// Check headers from any response
const remaining = parseInt(response.headers['x-ratelimit-remaining']);
const resetTime = parseInt(response.headers['x-ratelimit-reset']);

if (remaining < 5 && operations.length > 5) {
  const waitTime = resetTime - Math.floor(Date.now() / 1000);
  console.log(`Low on requests. Waiting ${waitTime}s before bulk operation...`);
  await sleep(waitTime * 1000);
}
```

### 4. Spread requests over time

For non-urgent bulk operations, spread requests evenly:

```javascript
async function bulkUpdate(agents, updateFn) {
  const REQUESTS_PER_MINUTE = 25; // Stay under the limit
  const DELAY_MS = 60000 / REQUESTS_PER_MINUTE; // ~2.4 seconds

  for (const agent of agents) {
    await updateFn(agent);
    await sleep(DELAY_MS);
  }
}
```

### 5. Use pagination wisely

Fetch only what you need:

```
# Good: small pages, specific queries
list_apps(limit=10, offset=0)
search_conversations(appId="xxx", query="Cresnet timeout", limit=20)

# Avoid: large fetches you don't need
list_apps(limit=1000)
export_conversations(appId="xxx")  # Use sparingly
```

## Upgrading your limits

Need higher limits? Upgrade your subscription:

| Current tier | Next tier | Limit increase |
|--------------|-----------|----------------|
| BUILDER | STUDIO | 30 to 60 req/min (2x) |
| STUDIO | STUDIO_PRO | 60 to 120 req/min (2x) |
| STUDIO_PRO | ENTERPRISE | 120 to Unlimited |

[Upgrade Your Plan](https://app.avcodex.com/settings/billing)

## Common scenarios

### Bulk agent creation

**Problem:** Creating 50 client-specific support agents (one per managed-services site) hits the rate limit.

**Solution (BUILDER tier):**
```javascript
// 30 requests/minute = ~2 seconds between requests
for (const agentConfig of agentConfigs) {
  await createAgent(agentConfig);
  await sleep(2000); // 2 second delay
}
// Total time: ~100 seconds for 50 agents
```

### Analytics dashboard

**Problem:** Fetching analytics for 20 client-specific agents exceeds the limit.

**Solution:**
```javascript
// Option 1: Fetch in batches
const batches = chunk(agentIds, 5);
for (const batch of batches) {
  await Promise.all(batch.map(id => getAgentAnalytics(id)));
  await sleep(10000); // Wait 10s between batches
}

// Option 2: Cache results.
// Analytics don't change by the second. Cache for 5+ minutes.
```

### CI/CD integration

**Problem:** Automated deployments need multiple tool calls.

**Solution:**
```yaml
# In your CI pipeline
steps:
  - name: Update AVCodex Agent
    run: |
      # Use retry logic
      ./update-agent.sh --retry-on-rate-limit
    env:
      AVCODEX_RETRY_DELAY: 60
      AVCODEX_MAX_RETRIES: 3
```

## Rate limit FAQ

**Q: Do rate limits apply per user or per organization?**
A: Per authenticated user (OAuth token or API key). Each team member has their own limit.

**Q: Does reading consume the same rate as writing?**
A: Yes. All tool calls count equally against the rate limit.

**Q: What happens if I'm rate-limited mid-workflow?**
A: Implement retry logic with exponential backoff. Your MCP client should handle 429 responses gracefully.

**Q: Can I request higher limits for a specific use case?**
A: Enterprise customers can negotiate custom limits. Contact sales@avcodex.com for details.

---

## Next steps

- Tools Reference. All available tools.
- Common Workflows. Efficient usage patterns.
- Authentication. Token management.

*AVCodex · Your AV expertise. Amplified by AI.*
