# Limites de taxa

MoreLogin aplica limites no gateway para proteger a API. A configuração de produção confirmada para API e Open API é de 200 solicitações por minuto com capacidade burst de 10.

## Contrato de implementação atual

| Item | Comportamento em produção |
|  --- | --- |
| Algoritmo | GCRA (Generic Cell Rate Algorithm) |
| Configuração da API | `rate=200`, `burst=10`, `period=1m` |
| Configuração da Open API | `rate=200`, `burst=10`, `period=1m` |
| Recuperação sustentada | Um permite a cada 0,3 segundos, ou cerca de 3,33 permites por segundo |
| Burst | Até 10 permites podem ficar disponíveis imediatamente |
| Chave de escopo da Open API | Caminho da requisição + ID da equipe |
| Chave de escopo da API | Caminho da requisição + ID da equipe; sem o ID da equipe, recorre ao ID de API e depois ao IP do cliente |
| Substituições em tempo de execução | Regras de API por rota ou por equipe podem substituir a configuração padrão |
| Requisições em lote | Uma requisição HTTP consome um permite do gateway; a contagem de itens não é usada pelo limitador |


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


## Resposta de limite

```json
{
  "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`.


## Novas tentativas seguras

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

```python
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")
```

## Reduzir solicitações

- Prefer batch endpoints when their semantics match the operation.
- Faça cache de dados de referência como fusos horários, idiomas, kernels e modelos de aparelho.
- Poll asynchronous operations with increasing intervals and stop at a terminal state.
- Do not blindly retry create, purchase, upload-registration, or schedule-creation requests.