Skip to main content

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 TypeDefaultMaximumDescription
Per Minute1001,000Actions per minute per agent
Per Hour1,00010,000Actions per hour per agent
Per Day10,000100,000Actions per day per agent

Per-API-Key Limits

API keys have their own rate limits:

TierRequests/MinuteRequests/HourDescription
Standard1001,000Default for new API keys
Professional5005,000For verified production apps
Enterprise2,00020,000Custom limits for enterprise

Per-Organization Limits

Organization-wide limits apply across all users and keys:

Limit TypeStandardProfessionalEnterprise
Total Actions/Hour10,00050,000Custom
Concurrent Requests50200Custom
Storage (audit logs)100 GB1 TBCustom

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
HeaderDescription
X-RateLimit-LimitMaximum requests allowed in the current window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp when the limit resets
X-RateLimit-Reset-AfterSeconds 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:

TierBurst AllowanceBurst Duration
Standard150% of limit30 seconds
Professional200% of limit60 seconds
Enterprise300% of limit120 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:

  1. Standard Process: Submit request through admin console
  2. Enterprise: Contact your account manager
  3. Emergency: Use support chat for urgent needs

Include in your request:

  • Current usage patterns
  • Reason for increase
  • Expected peak usage
  • Business justification