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

# Rate Limits

> API rate limits, headers, and best practices for the HopX API. Understand rate limit policies, check rate limit headers, handle rate limit errors, and implement best practices for high-volume API usage. Essential for building scalable applications with HopX APIs. Includes rate limit examples and optimization strategies.

The HopX API implements rate limiting to ensure fair usage and system stability. Rate limits vary by endpoint and account plan.

## Rate Limit Tiers

### Default Limits

| Endpoint Type     | Limit        | Window     |
| ----------------- | ------------ | ---------- |
| Control Plane API | 100 requests | per minute |
| VM Agent API      | 300 requests | per minute |
| Template Builds   | 10 builds    | per hour   |
| Sandbox Creation  | 20 sandboxes | per minute |

### Plan-Based Limits

Rate limits may vary based on your account plan:

* **Free Tier** - Default limits
* **Pro Tier** - 2x default limits
* **Enterprise** - Custom limits

## Rate Limit Headers

Every API response includes rate limit headers:

```
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1706400060
```

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

## Rate Limit Exceeded

When you exceed the rate limit, you'll receive a `429 Too Many Requests` response:

```json theme={null}
{
  "error": "Rate limit exceeded: 100 requests per minute",
  "code": "RATE_LIMIT_EXCEEDED",
  "request_id": "req_abc123",
  "retry_after": 30
}
```

The `retry_after` field indicates how many seconds to wait before retrying.

## Best Practices

### 1. Monitor Rate Limit Headers

```python theme={null}
import requests

response = requests.get(
    "https://api.hopx.dev/v1/sandboxes",
    headers={"Authorization": "Bearer $HOPX_API_KEY"}
)

remaining = int(response.headers.get('X-RateLimit-Remaining', 0))
limit = int(response.headers.get('X-RateLimit-Limit', 0))

print(f"Rate limit: {remaining}/{limit}")

if remaining < 10:
    print("Warning: Approaching rate limit")
```

### 2. Implement Exponential Backoff

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

def make_request_with_backoff(url, headers, max_retries=5):
    for attempt in range(max_retries):
        response = requests.get(url, headers=headers)
        
        if response.status_code != 429:
            return response
        
        # Rate limited - wait and retry
        retry_after = int(response.headers.get('Retry-After', 2 ** attempt))
        print(f"Rate limited. Retrying after {retry_after}s")
        time.sleep(retry_after)
    
    raise Exception("Max retries exceeded")
```

### 3. Batch Operations

Instead of making many individual requests, batch operations when possible:

```python theme={null}
# Bad: One request per sandbox
for sandbox_id in sandbox_ids:
    response = requests.get(
        f"https://api.hopx.dev/v1/sandboxes/{sandbox_id}",
        headers=headers
    )
    process(response.json())

# Good: One request for all sandboxes
response = requests.get(
    "https://api.hopx.dev/v1/sandboxes",
    headers=headers
)
sandboxes = response.json()["data"]
for sandbox in sandboxes:
    process(sandbox)
```

### 4. Cache Responses

Cache responses that don't change frequently:

```python theme={null}
import time
from functools import lru_cache

@lru_cache(maxsize=100)
def get_template(template_id, cache_time):
    response = requests.get(
        f"https://api.hopx.dev/v1/templates/{template_id}",
        headers={"Authorization": "Bearer $HOPX_API_KEY"}
    )
    return response.json()

# Cache for 5 minutes
cache_key = int(time.time() // 300)
template = get_template("code-interpreter", cache_key)
```

### 5. Distribute Requests Over Time

```python theme={null}
import time

sandboxes_to_create = 50
rate_limit_per_minute = 20
delay = 60 / rate_limit_per_minute  # 3 seconds

for i in range(sandboxes_to_create):
    create_sandbox()
    if i < sandboxes_to_create - 1:
        time.sleep(delay)
```

## Rate Limit Strategies

### Sliding Window

Rate limits use a sliding window algorithm, not a fixed window. This means:

* Limits are enforced per 60-second rolling window
* Request counts decay as time passes
* Burst traffic is allowed up to the limit

### Per-Endpoint Limits

Some endpoints have separate rate limits:

| Endpoint               | Limit      | Reason                       |
| ---------------------- | ---------- | ---------------------------- |
| `/v1/templates/build`  | 10/hour    | Resource-intensive operation |
| `/v1/sandboxes` (POST) | 20/minute  | Prevent abuse                |
| `/v1/sandboxes` (GET)  | 100/minute | Standard limit               |

## Handling Rate Limits in Production

### Production-Ready Handler

```python theme={null}
import time
import requests
from typing import Optional

class RateLimitedClient:
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.hopx.dev"
        self.headers = {"Authorization": f"Bearer {api_key}"}
    
    def request(self, method: str, path: str, **kwargs) -> requests.Response:
        max_retries = 5
        
        for attempt in range(max_retries):
            response = requests.request(
                method,
                f"{self.base_url}{path}",
                headers=self.headers,
                **kwargs
            )
            
            # Success
            if response.status_code < 400:
                return response
            
            # Rate limited
            if response.status_code == 429:
                retry_after = int(response.headers.get('Retry-After', 2 ** attempt))
                print(f"Rate limited. Waiting {retry_after}s (attempt {attempt + 1}/{max_retries})")
                time.sleep(retry_after)
                continue
            
            # Other errors - don't retry
            response.raise_for_status()
        
        raise Exception("Max retries exceeded due to rate limiting")
    
    def get(self, path: str, **kwargs) -> requests.Response:
        return self.request("GET", path, **kwargs)
    
    def post(self, path: str, **kwargs) -> requests.Response:
        return self.request("POST", path, **kwargs)

# Usage
client = RateLimitedClient("$HOPX_API_KEY")
response = client.get("/v1/sandboxes")
sandboxes = response.json()
```

## Increasing Rate Limits

If you need higher rate limits:

1. **Upgrade Your Plan** - Higher tiers include increased limits
2. **Contact Support** - Request custom limits for your use case
3. **Optimize Your Code** - Reduce unnecessary API calls

## Monitoring Usage

Check your current usage via the API:

```bash theme={null}
curl https://api.hopx.dev/v1/account/usage \
  -H "Authorization: Bearer $HOPX_API_KEY"
```

Response:

```json theme={null}
{
  "rate_limits": {
    "control_plane": {
      "limit": 100,
      "remaining": 85,
      "reset_at": "2025-01-28T00:01:00Z"
    },
    "vm_agent": {
      "limit": 300,
      "remaining": 250,
      "reset_at": "2025-01-28T00:01:00Z"
    }
  }
}
```

## Related

* **[API Introduction](/api/introduction)** - Learn about the HopX API
* **[Error Handling](/api/concepts/errors)** - Handle rate limit errors
* **[Pagination](/api/concepts/pagination)** - Paginate list results
* **[Troubleshooting](/api/concepts/troubleshooting)** - Debug API issues
* [CLI Reference](/cli/introduction) - Command-line interface

## Next Steps

* **[Errors](/api/concepts/errors)** - Error handling and codes
* **[Pagination](/api/concepts/pagination)** - Paginating list results
* **[Troubleshooting](/api/concepts/troubleshooting)** - Common issues and solutions
