Перейти к содержимому
Last updated

Ограничения скорости

MoreLogin применяет ограничение на шлюзе для стабильности API. Подтвержденная производственная конфигурация для API и Open API: 200 запросов в минуту и burst 10.


Текущий контракт реализации

ПараметрПоведение в продакшене
АлгоритмGCRA (Generic Cell Rate Algorithm)
Настройка APIrate=200, burst=10, period=1m
Настройка Open APIrate=200, burst=10, period=1m
Постоянное восстановлениеОдно разрешение каждые 0,3 секунды, примерно 3,33 разрешения в секунду
BurstДо 10 разрешений могут быть доступны сразу
Ключ области Open APIПуть запроса + ID команды
Ключ области APIПуть запроса + ID команды; если ID команды недоступен, используется ID API, затем IP клиента
Переопределения во время работыПравила API для маршрута или команды могут переопределить настройку по умолчанию
Пакетные запросыОдин HTTP-запрос расходует одно разрешение шлюза; число элементов ограничителем не учитывается

These are the confirmed production gateway values, not the Java fallback (rate=1, burst=1, period=1s). At rate=200 over 60 seconds, one permit is restored every 0.3 seconds (approximately 3.33 per second), and up to 10 permits can accumulate. The localhost Local API does not traverse this public cloud gateway.

  • rate: permits restored during period
  • burst: maximum permits immediately available
  • period: restoration interval

Ответ при ограничении

{
  "code": 35000,
  "msg": "API requests are too frequent. Please try again later.",
  "data": null,
  "requestId": "request-trace-id"
}
  • The current response writer does not explicitly set HTTP 429; inspect body code even when HTTP status is 200.
  • No Retry-After, RateLimit-*, or X-RateLimit-* headers are currently emitted.
  • Handle HTTP 429 defensively for future gateway or edge-proxy changes.
  • The message language can vary; branch on code, not msg.

Безопасные повторы

Retry reads with exponential backoff and jitter. For writes, query current state before retrying. A general public idempotency-key header is not currently documented.

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")
        delay = float(retry_after) if retry_after and retry_after.isdigit() else min(2 ** attempt, 30) + random.uniform(0, 0.5)
        time.sleep(delay)

    raise RuntimeError("Rate limit retry budget exhausted")

Снижение числа запросов

  • Prefer batch endpoints when their semantics match the operation.
  • Кэшируйте справочные данные: часовые пояса, языки, ядра и модели устройств.
  • Poll asynchronous operations with increasing intervals and stop at a terminal state.
  • Do not blindly retry create, purchase, upload-registration, or schedule-creation requests.