Rate Limits
The Ascend API implements rate limiting to ensure fair usage and platform stability. Rate limits are applied at multiple levels to protect both individual users and the overall system.
Rate Limit Tiers
Per-Agent Limits
Each registered agent has configurable rate limits:
| Limit Type | Default | Maximum | Description |
|---|---|---|---|
| Per Minute | 100 | 1,000 | Actions per minute per agent |
| Per Hour | 1,000 | 10,000 | Actions per hour per agent |
| Per Day | 10,000 | 100,000 | Actions per day per agent |
Per-API-Key Limits
API keys have their own rate limits:
| Tier | Requests/Minute | Requests/Hour | Description |
|---|---|---|---|
| Standard | 100 | 1,000 | Default for new API keys |
| Professional | 500 | 5,000 | For verified production apps |
| Enterprise | 2,000 | 20,000 | Custom limits for enterprise |
Per-Organization Limits
Organization-wide limits apply across all users and keys:
| Limit Type | Standard | Professional | Enterprise |
|---|---|---|---|
| Total Actions/Hour | 10,000 | 50,000 | Custom |
| Concurrent Requests | 50 | 200 | Custom |
| Storage (audit logs) | 100 GB | 1 TB | Custom |
Rate Limit Headers
All API responses include rate limit information in headers:
HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1705762800
X-RateLimit-Reset-After: 45
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed in the current window |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp when the limit resets |
X-RateLimit-Reset-After | Seconds until the limit resets |
Rate Limit Response
When you exceed a rate limit, you receive a 429 Too Many Requests response:
{
"detail": "Rate limit exceeded: 100 requests per minute",
"error_code": "RATE_LIMIT_EXCEEDED",
"status": 429,
"rate_limit": {
"limit": 100,
"remaining": 0,
"reset_at": "2026-01-20T14:31:00Z",
"retry_after": 45,
"window": "minute"
},
"headers": {
"Retry-After": "45"
}
}
The Retry-After header indicates how long to wait before retrying.
Configuring Agent Rate Limits
Admins can configure rate limits for registered agents:
Set Rate Limits
PUT /api/registry/agents/{agent_id}/rate-limits
Request Body:
{
"max_actions_per_minute": 200,
"max_actions_per_hour": 2000,
"max_actions_per_day": 20000
}
Response:
{
"success": true,
"agent_id": "my-agent",
"rate_limits": {
"per_minute": 200,
"per_hour": 2000,
"per_day": 20000
},
"configured_by": "admin@company.com",
"compliance": "SEC-068 / NIST SI-4"
}
View Agent Usage
GET /api/registry/agents/{agent_id}/usage
Response:
{
"agent_id": "my-agent",
"rate_limits": {
"per_minute": {
"limit": 200,
"current": 45,
"remaining": 155
},
"per_hour": {
"limit": 2000,
"current": 892,
"remaining": 1108
},
"per_day": {
"limit": 20000,
"current": 5421,
"remaining": 14579
}
},
"budget": {
"max_daily_usd": 100.00,
"current_spend_usd": 23.45,
"remaining_usd": 76.55
}
}
Configuring API Key Rate Limits
When generating an API key, you can set custom rate limits:
POST /api/keys/generate
Request Body:
{
"name": "High-Volume Integration",
"rate_limit": {
"max_requests": 500,
"window_seconds": 60
}
}
Best Practices
1. Implement Exponential Backoff
When you receive a 429 response, use exponential backoff:
import time
import random
def make_request_with_backoff(func, max_retries=5):
for attempt in range(max_retries):
try:
response = func()
if response.status_code != 429:
return response
# Get retry delay from header or default
retry_after = int(response.headers.get('Retry-After', 60))
# Add jitter to prevent thundering herd
jitter = random.uniform(0, 0.1 * retry_after)
wait_time = retry_after + jitter
print(f"Rate limited. Waiting {wait_time:.1f}s...")
time.sleep(wait_time)
except Exception as e:
if attempt == max_retries - 1:
raise
time.sleep(2 ** attempt)
raise Exception("Max retries exceeded")
2. Monitor Rate Limit Headers
Track your usage to avoid hitting limits:
class RateLimitTracker:
def __init__(self):
self.remaining = None
self.reset_at = None
def update_from_response(self, response):
self.remaining = int(response.headers.get('X-RateLimit-Remaining', 100))
self.reset_at = int(response.headers.get('X-RateLimit-Reset', 0))
def should_wait(self):
if self.remaining is not None and self.remaining < 5:
return True
return False
def wait_time(self):
if self.reset_at:
return max(0, self.reset_at - time.time())
return 60
3. Batch Requests When Possible
Instead of individual requests, batch operations:
# Instead of this:
for item in items:
client.actions.submit(item)
# Do this:
client.actions.submit_batch(items) # Single request for multiple actions
4. Use Webhooks for Async Operations
Instead of polling for status updates, configure webhooks:
# Configure webhook to receive updates
client.webhooks.create(
name="Action Updates",
target_url="https://your-server.com/webhooks/ascend",
event_types=["action.approved", "action.denied"]
)
# Submit action and wait for webhook
result = client.actions.submit(...)
# Webhook will notify you when decision is made
5. Cache Responses When Appropriate
For data that doesn't change frequently:
from functools import lru_cache
from datetime import datetime, timedelta
@lru_cache(maxsize=100)
def get_agent_config(agent_id):
"""Cache agent config for 5 minutes"""
return client.agents.get(agent_id)
# Clear cache periodically
def refresh_cache():
get_agent_config.cache_clear()
Handling Different Rate Limit Types
Agent Rate Limit
Occurs when a specific agent exceeds its limits:
{
"error_code": "AGENT_RATE_LIMIT",
"detail": "Agent 'my-agent' exceeded rate limit: 100/minute",
"agent_id": "my-agent",
"limit": 100,
"window": "minute"
}
Resolution: Reduce the frequency of actions from this agent or increase its limits.
API Key Rate Limit
Occurs when an API key exceeds its limits:
{
"error_code": "API_KEY_RATE_LIMIT",
"detail": "API key rate limit exceeded",
"key_prefix": "owkai_admin_abc...",
"limit": 100,
"window": "minute"
}
Resolution: Wait for reset or use a different API key.
Organization Rate Limit
Occurs when the entire organization exceeds limits:
{
"error_code": "ORG_RATE_LIMIT",
"detail": "Organization rate limit exceeded",
"organization_id": 123,
"limit": 10000,
"window": "hour"
}
Resolution: Contact support for limit increase or optimize usage patterns.
Rate Limit Exemptions
For critical operations, you can request rate limit exemptions:
Emergency Operations
During security incidents, use the emergency flag:
{
"agent_id": "security-bot",
"action_type": "block_ip",
"description": "Emergency IP block",
"emergency": true
}
Emergency operations may bypass certain rate limits but are logged for audit.
Burst Allowance
Enterprise plans include burst allowances for temporary spikes:
| Tier | Burst Allowance | Burst Duration |
|---|---|---|
| Standard | 150% of limit | 30 seconds |
| Professional | 200% of limit | 60 seconds |
| Enterprise | 300% of limit | 120 seconds |
Monitoring and Alerts
Rate Limit Metrics
Monitor your rate limit usage in the admin console:
GET /api/admin/metrics/rate-limits
Response:
{
"organization_id": 123,
"period": "24h",
"metrics": {
"total_requests": 45892,
"rate_limited_requests": 127,
"rate_limit_percentage": 0.28,
"peak_requests_per_minute": 892,
"average_requests_per_minute": 318
},
"top_agents": [
{"agent_id": "data-bot", "requests": 12450},
{"agent_id": "security-bot", "requests": 8921}
],
"recommendations": [
"Consider increasing rate limits for 'data-bot' agent"
]
}
Configure Rate Limit Alerts
Set up alerts for approaching limits:
POST /api/webhooks
{
"name": "Rate Limit Alerts",
"target_url": "https://your-server.com/alerts",
"event_types": [
"rate_limit.warning",
"rate_limit.exceeded"
],
"event_filters": {
"threshold_percent": 80
}
}
Requesting Limit Increases
Contact support for limit increases:
- Standard Process: Submit request through admin console
- Enterprise: Contact your account manager
- Emergency: Use support chat for urgent needs
Include in your request:
- Current usage patterns
- Reason for increase
- Expected peak usage
- Business justification