Entrar no app

Rate limits e idempotência

Entenda os limites de requisições por plano e como usar o header Idempotency-Key para evitar cobranças duplas.

Rate limits

Os limites se aplicam apenas a requisições autenticadas por API key. Sessões de browser (cookie) não são limitadas por esse sistema.

Limites por plano

PlanoReq/minReq/diaMax itens/batch
Basic301.00020
Pro605.000100
Scale12020.000500
Sem plano102005

Os limites são definidos por API key no momento da criação. Uma chave criada no plano Basic mantém os limites Basic mesmo que o plano seja atualizado depois. Use PATCH /api/v1/api-keys/:id/limits para ajustar individualmente (teto absoluto: 1.000 req/min, 200.000 req/dia).

Como funciona

O rate limit usa janela fixa (fixed-window) por chave, com dois contadores independentes: um por minuto e um por dia. Cada requisição autenticada por API key incrementa ambos e é bloqueada quando qualquer um dos dois estoura.

Headers de rate limit

Todas as requisições autenticadas por API key recebem:

HeaderDescricao
ratelimit-limitLimite de requisições por minuto para esta chave
ratelimit-remainingRequisições restantes na janela atual
ratelimit-resetSegundos ate o reset da janela atual
retry-afterPresente apenas em 429: segundos para aguardar (60s)

Exemplo de headers em uma requisição normal:

ratelimit-limit: 60
ratelimit-remaining: 43
ratelimit-reset: 27

Quando o limite é atingido (HTTP 429):

{
  "type": "urn:vestiai:error:rate_limit",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Limite de requisições da API key excedido (61/60 por minuto, 4992/5000 por dia)",
  "instance": "/api/v1/generations"
}

Aguarde o número de segundos indicado em retry-after antes de retentar. Para detalhes sobre todos os tipos de erro, veja o guia de Erros.

Idempotência

O header Idempotency-Key garante que uma requisição de mutação seja executada exatamente uma vez, mesmo que você a reenvie por timeout ou falha de rede. Isso é especialmente importante para evitar cobranças duplas de crédito.

Como usar

Adicione o header em qualquer POST, PATCH, PUT ou DELETE:

Idempotency-Key: seu-uuid-unico-aqui

Recomendacoes:

  • Use UUID v4 gerado no cliente para cada operação lógica.
  • Maximo de 255 caracteres.
  • Escopo por caller: a mesma chave de dois usuários distintos nunca colide.

Comportamento

CenarioResposta
Primeira requisiçãoProcessa normalmente, retorna resultado
Retentativa apos 2xx bem-sucedidoRetorna resposta cacheada + header x-idempotent-replay: true
Requisição concorrente com mesma key409 "em processamento"
Mesma key, rota diferente409 "chave já usada em rota diferente"
Mesma key, body diferente422 urn:vestiai:error:idempotency_key_reuse
Requisição que falhou (non-2xx)Marker liberado, retentativa pode prosseguir

TTL e escopo

  • Respostas 2xx são cacheadas por 24 horas.
  • Erros não são cacheados: você pode retentar livremente após uma falha.
  • O escopo é (caller, key): cada API key é um caller distinto, então a mesma chave de string vinda de duas API keys diferentes nunca colide.

Exemplo

# Primeira chamada - processa e debita 1 credito
curl -X POST https://api.vestiai.com.br/api/v1/generations \
  -H "Authorization: Bearer sk_live_SUA_CHAVE" \
  -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
  -H "Content-Type: application/json" \
  -d '{ "clothingUploadIds": [42], "modelId": 7, "backgroundId": 3 }'

# Segunda chamada com a mesma key - retorna resposta cacheada, sem novo debito
curl -X POST https://api.vestiai.com.br/api/v1/generations \
  -H "Authorization: Bearer sk_live_SUA_CHAVE" \
  -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
  -H "Content-Type: application/json" \
  -d '{ "clothingUploadIds": [42], "modelId": 7, "backgroundId": 3 }'
# Resposta inclui: x-idempotent-replay: true

Monitorando o consumo

Para acompanhar uso de créditos e limites da chave atual:

curl https://api.vestiai.com.br/api/v1/usage \
  -H "Authorization: Bearer sk_live_SUA_CHAVE"

Retorna credits, consumed no período, resetAt (ISO timestamp do próximo reset) e limits completos da chave.

Para registrar um webhook e receber notificações sem polling, veja o guia de Webhooks.