Rate Limits and Quotas
Current enforced limits for Leenops REST and MCP requests.
Leenops currently has several independently enforced limits. There is not yet
one universal plan-tier requests-per-minute policy for every /api/v1 route.
Hosted MCP
The hosted MCP session, tool-list, and tool-call endpoints enforce:
| Dimension | Limit |
|---|---|
| Source IP | 600 requests per minute |
| Workspace | 600 requests per minute |
Responses include:
X-RateLimit-Limit
X-RateLimit-Remaining
X-RateLimit-Reset
Retry-AfterRetry-After is included on 429 responses.
REST rate limiting
REST enforcement is currently route-family specific:
| Route set | Current behavior |
|---|---|
| Selected Time and newer module routes | Per-IP cap of 120/minute plus workspace read/write buckets |
| Workspace read bucket used by those routes | 300/minute |
| Workspace write bucket used by those routes | 60/minute |
| Selected CRM reads | Monthly API-call quota metering |
| Other v1 routes | Authentication and authorization apply, but no single shared per-minute limiter is guaranteed |
Because adoption is not uniform, do not infer a limit for an endpoint that does not return rate-limit headers.
Monthly API quota
Selected CRM endpoints increment a workspace API-usage counter and can return:
{
"error": "API quota exceeded",
"code": "QUOTA_EXCEEDED",
"message": "Monthly API call limit reached. Upgrade your plan for higher limits."
}This response uses HTTP 429, X-Quota-Exceeded: api_calls_monthly, and a
Retry-After value. The monthly amount comes from the workspace's configured
plan quota; it is not the same as a per-minute limit.
Agent-trial quota
Human-approved agent-trial credentials additionally have:
- A seven-day credential lifetime.
- A maximum of 250 successful tool-call consumption attempts under the current contract.
- A guarded tool allowlist.
The trial contract and capability manifest are authoritative if they specify a stricter value.
Client behavior
For reliable test clients:
- Honor
Retry-After. - Use exponential backoff with jitter for
429, network errors, and retryable5xx. - Do not retry validation, authentication, or permission failures unchanged.
- Cache reads and prefer webhooks over polling.
- Deduplicate mutations with application-level idempotency where the endpoint supports it.
Example:
const response = await fetch(url, options);
if (response.status === 429) {
const retryAfterSeconds = Number(response.headers.get("retry-after") ?? "60");
// Wait, add jitter, and retry within your own bounded retry budget.
}What is not currently promised
The public contract does not currently promise:
- Starter/Professional/Enterprise limits of 100/500/2,000 requests per minute.
- A universal 50%-of-tier write limit.
- A universal 10/minute bulk/export tier.
- A self-service endpoint-specific rate-limit increase.
- Rate-limit headers on every REST response.

