MoreLogin uses gateway rate limiting to protect API stability. The confirmed production configuration allows 200 requests per minute with a burst capacity of 10 for both API and Open API traffic.
| Item | Production behavior |
|---|---|
| Algorithm | GCRA (Generic Cell Rate Algorithm) |
| API configuration | rate=200, burst=10, period=1m |
| Open API configuration | rate=200, burst=10, period=1m |
| Sustained recovery | One permit every 0.3 seconds, or approximately 3.33 permits per second |
| Burst | Up to 10 permits can be immediately available |
| Open API scope key | Request path + team ID |
| API scope key | Request path + team ID; falls back to API ID, then client IP when team ID is unavailable |
| Runtime overrides | Route- or team-specific API rules can override the default API configuration |
| Batch requests | One HTTP request consumes one gateway permit; item count is not used by the gateway limiter |
These values are the production gateway configuration, not the Java configuration object's unconfigured fallback (rate=1, burst=1, period=1s). Clients should use the production values for capacity planning.
The localhost Local API does not traverse the public Open API gateway. Its effective limit depends on the desktop client and the called operation; the cloud gateway defaults above must not be applied to it.
rate: number of permits restored duringperiodburst: maximum number of permits that can be immediately availableperiod: permit restoration interval
With rate=200, period=60s, and burst=10, the gateway restores permits continuously at approximately 3.33 per second and allows at most 10 accumulated permits to be consumed immediately. This is a GCRA limit, not a fixed-window counter that resets all 200 permits at the start of each minute.
The current gateway implementation returns business error code 35000:
{
"code": 35000,
"msg": "API requests are too frequent. Please try again later.",
"data": null,
"requestId": "request-trace-id"
}Current implementation details:
- The gateway response writer does not explicitly set HTTP
429; clients must inspect the response bodycodeeven when the HTTP status is200. - No
Retry-After,RateLimit-*, orX-RateLimit-*response headers are currently emitted. - Clients should also handle HTTP
429defensively so they remain compatible with future gateway or edge-proxy changes. - Include
requestIdwhen contacting support.
Use exponential backoff with jitter. Retry reads and explicitly idempotent operations automatically. For state-changing operations, first query the resource state or use an endpoint-specific recovery flow; the public API does not currently document a general idempotency-key header.
import random
import time
import requests
def api_request_with_retry(url, payload, headers=None, max_retries=4):
for attempt in range(max_retries):
response = requests.post(url, json=payload, headers=headers, timeout=30)
try:
body = response.json()
except ValueError:
body = {}
limited = response.status_code == 429 or body.get("code") == 35000
if not limited:
return response
retry_after = response.headers.get("Retry-After")
if retry_after and retry_after.isdigit():
delay = float(retry_after)
else:
delay = min(2 ** attempt, 30) + random.uniform(0, 0.5)
time.sleep(delay)
raise RuntimeError("Rate limit retry budget exhausted")| Operation type | Automatic retry guidance |
|---|---|
| List, detail, status, and other read/query operations | Retry with backoff and jitter |
| Power-on, power-off, start, or stop operations | Query current state before retrying |
| Create, purchase, upload registration, and schedule creation | Do not blindly retry; first check whether the resource or task was created |
| Batch operations | Treat the entire HTTP request as one attempt; inspect per-item results where provided |
- Prefer batch endpoints when they provide the required semantics.
- Cache reference data such as time zones, languages, kernels, and device models.
- Poll asynchronous operations with increasing intervals and stop at a documented terminal state.
- Spread large workloads instead of sending all requests at once.