Skip to content
Dashboard

Rate Limits

LimitDefault value
Sustained1,000 requests per minute per credential
Burst50 requests per second per credential
  • API keys are limited per key. SuiteOp can configure an individual key with a higher per-minute limit; its burst allowance then grows to match (the larger of 50 or the minute limit ÷ 60, rounded up). The X-RateLimit-Limit header always shows the minute limit that applies to your key.
  • OAuth tokens are limited per app and user pair, at the default limits. Acting in a second organization doesn’t give the pair a second budget.

The sustained limit uses a fixed window aligned to the clock minute, not a rolling window. The counter resets at the start of every minute (X-RateLimit-Reset).

Every authenticated request is counted, including requests that end in an error and requests to paths that don’t exist. The REST API and the MCP server draw from the same budget for the same credential.

Every authenticated response includes rate limit headers, whether it succeeds or fails:

HeaderDescription
X-RateLimit-LimitRequests allowed per minute for this credential
X-RateLimit-RemainingRequests remaining in the current minute
X-RateLimit-ResetUnix timestamp (seconds) when the current minute window ends

These headers are not present on 401 responses (unauthenticated requests).

A rate-limited response has status 429 and includes a Retry-After header in whole seconds:

HTTP/1.1 429 Too Many Requests
Retry-After: 14
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1720000020
{
"error": {
"type": "rate_limit_error",
"code": "RATE_LIMITED",
"message": "API rate limit exceeded",
"details": {
"vendor": "public-api",
"retryAfterSeconds": 14,
"rateLimit": { "limit": 1000, "remaining": 0, "resetAtEpochSeconds": 1720000020 }
}
},
"meta": { "requestId": "3f1c9a52-…" }
}

The headers tell you which limit you hit:

You exceededRetry-AfterX-RateLimit-Remaining
The minute limitSeconds until the next minute starts0
The burst limit1What is left of the minute limit, which can still be in the hundreds

A burst denial can therefore show Retry-After: 1 next to a large X-RateLimit-Remaining. That isn’t a contradiction: you still have minute budget, but you sent too many requests within one second.

If the rate limiter itself is unavailable, the API refuses requests with 429 rather than letting them through unmetered. Treat it like any other 429.

A few operations call an AI model to produce their result: create_email_template, modify_email_template, initializeLanguageTranslations, retranslateGuideText, create_workflow and modify_workflow. On top of the per-credential limit, these share a separate per-organization budget (by default 10 calls per 60 seconds), no matter how many keys the organization uses. Going over it returns 429 rate_limit_error with the message Model-backed action rate limit exceeded and a Retry-After header. If that limiter is unavailable, the 429 comes without Retry-After; back off (for example 60 seconds) before retrying. This 429 usually leaves X-RateLimit-Remaining above 0, because that header reports your per-credential minute budget, so pace retries by Retry-After, not by Remaining.

For automated clients:

  1. Check X-RateLimit-Remaining on each response. If it is low, slow down before you hit 0.
  2. On a 429, wait Retry-After seconds before sending the next request.
  3. Spread requests evenly across the minute rather than sending them all at once, so you don’t trip the per-second burst limit.
Terminal window
# Example: request, and on a 429 sleep for the Retry-After value
while true; do
status=$(curl -s -o body.json -D headers.txt -w "%{http_code}" \
-H "Authorization: Bearer sk_live_your_key_here" \
https://api-us.suiteop.com/api/v1/tasks)
if [ "$status" = "429" ]; then
retry_after=$(grep -i '^retry-after:' headers.txt | awk '{print $2}' | tr -d '\r')
sleep "${retry_after:-1}"
continue
fi
# process body.json here
sleep 1
done