Saltar para o conteúdo principal

Documentation Index

Fetch the complete documentation index at: https://docs.vmarea.com/llms.txt

Use this file to discover all available pages before exploring further.

A API pública da VMArea usa dois buckets encadeados, ambos com Redis como backend — os limites são compartilhados entre todas as instâncias da API.

Limites atuais

BucketLimiteChaveado porAplica-se a
API pública (por token)600 requisições / minuto (10 RPS sustentado)ID do token de APIToda requisição /api/public/v1/* após autenticação bem-sucedida com x-api-key
Fallback global (por IP)100 requisições / minutoEndereço IPTodo o tráfego — principalmente para conter abusos em rotas não autenticadas (login, cadastro)
O bucket por token garante que clientes pesados e clientes atrás de NAT compartilhado não penalizem uns aos outros. Combine com o cabeçalho Idempotency-Key para que retentativas seguras não consumam cota extra — veja Idempotência.

Resposta 429

Quando você excede algum dos limites, a API retorna HTTP 429 Too Many Requests com o envelope padrão:
{
  "success": false,
  "error": "Rate limit exceeded for this API token: 600 requests per minute. Retry after 42."
}
A string error identifica qual bucket foi atingido (por token ou fallback global por IP).

Cabeçalhos

Toda resposta inclui os cabeçalhos padrão de rate limit; Retry-After é adicionado nas respostas 429.
CabeçalhoDescrição
X-RateLimit-LimitNúmero máximo de requisições permitidas na janela atual.
X-RateLimit-RemainingRequisições restantes na janela atual.
X-RateLimit-ResetSegundos até a janela reiniciar.
Retry-AfterSegundos para aguardar antes de tentar novamente (apenas em 429).

Tratando 429 no seu cliente

Leia Retry-After para o tempo mínimo de espera, depois aplique backoff exponencial com jitter começando em 1 segundo:
async function requestWithRetry(url, options, maxAttempts = 5) {
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    const res = await fetch(url, options);
    if (res.status !== 429) return res;

    const retryAfter = parseInt(res.headers.get("Retry-After") ?? "1", 10);
    const base = Math.max(retryAfter, 1) * 1000;
    const jitter = Math.random() * 1000;
    const delay = base * Math.pow(2, attempt - 1) + jitter;
    await new Promise((r) => setTimeout(r, delay));
  }
  throw new Error("Rate limit: max retry attempts exceeded");
}

Boas práticas

  • Use Idempotency-Key para escritas. Retentativas seguras não consomem cota extra nem criam recursos duplicados.
  • Agrupe leituras onde possível. Endpoints de listagem paginados são mais eficientes do que múltiplos GETs individuais.
  • Faça cache dos dados do catálogo. Planos, regiões e templates de SO mudam raramente — armazene-os localmente em vez de buscar repetidamente.
  • Use webhooks para mudanças de estado. Assinar vm.started, vm.stopped etc. evita polling em loop em GET /vms/:id.
  • Precisa de limites maiores? Entre em contato com o suporte — 10 RPS cobre praticamente todas as integrações, mas podemos aumentar os limites por token sob solicitação.