Rate limiting
Controle a frequência e a concorrência das chamadas à API Raims e trate respostas 429 com novas tentativas limitadas.
A API limita a frequência de chamadas e a quantidade de requisições em
andamento. Sua integração deve controlar os dois valores, tratar 429 Too Many Requests e distribuir o trabalho ao longo do tempo.
Use este guia ao preparar uma integração, investigar recusas por excesso ou planejar um aumento de volume. Os limites apresentados aqui são os da API Raims; as regras próprias de cada endpoint também precisam ser respeitadas.
Como os limites são compartilhados
A cota pertence à empresa e ao ambiente da chave de API. Todas as chaves da mesma empresa compartilham os limites naquele ambiente, mesmo quando as chamadas vêm de servidores, processos ou aplicações diferentes. Criar ou rotacionar uma chave não aumenta a cota. Produção e Sandbox têm cotas separadas.
Cada endpoint tem um limite adicional de frequência. O método HTTP e o caminho
da referência identificam o endpoint: GET /v1/charges/{id} compartilha a mesma cota para
todos os IDs. Já GET /v1/charges e POST /v1/charges têm cotas de endpoint
distintas e compartilham a cota total da empresa no ambiente.
Coordene o consumo entre os componentes da sua integração. Um controle local em cada processo, sozinho, não controla a soma de todos eles.
Limites da API por empresa e ambiente
Os valores abaixo são os limites padrão. Eles podem variar conforme os limites definidos para sua empresa.
| Limite | Produção | Sandbox |
|---|---|---|
| Total de requisições por segundo | 100 | 25 |
| Requisições por segundo em cada endpoint | 25 | 25 |
| Total de requisições em andamento | 50 | 50 |
Os limites se aplicam juntos. Em Produção, por exemplo, o teto total de 100 requisições por segundo não permite concentrar esse volume em um endpoint limitado a 25. No Sandbox, chamadas a endpoints diferentes também dividem o teto total de 25.
Considere esses valores tetos de uso, sem mantê-los como meta permanente de envio. Uma chamada HTTP pode consultar ou alterar um recurso; a cota não representa uma quantidade de pagamentos processados por segundo.
Frequência e concorrência
Frequência é a quantidade de chamadas enviadas ao longo do tempo. Concorrência é a quantidade que ainda não terminou. Uma consulta demorada continua ocupando capacidade mesmo quando nenhuma nova chamada é enviada.
Por exemplo, enviar dez chamadas por segundo que levam cinco segundos cada pode manter cerca de cinquenta chamadas em andamento. Reduzir somente a frequência não libera imediatamente as chamadas que já estão em execução.
Distribua o início das chamadas e limite quantas podem ficar em andamento.
Evite disparar um lote inteiro ao mesmo tempo. Picos curtos podem receber
429 mesmo quando a média observada está abaixo do teto; a passagem de um
segundo para outro não deve ser usada para concentrar dois lotes.
Interpretar o 429
429 RATE_LIMITED indica que a requisição foi recusada por excesso e não foi
executada. A resposta informa quanto esperar e qual controle ajustar:
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Cache-Control: no-store
Retry-After: 1
Raims-Rate-Limited-Reason: endpoint-rate
{
"error": {
"code": "RATE_LIMITED",
"message": "The API request limit was exceeded. Wait for Retry-After and reduce the request rate or the number of concurrent requests."
}
}Retry-After é um número inteiro positivo de segundos. Espere pelo menos
esse intervalo antes de repetir. O valor 1 acima é um exemplo; use sempre
o valor recebido na resposta.
Raims-Rate-Limited-Reason | O que ajustar |
|---|---|
global-rate | Reduza a frequência total de chamadas da empresa no ambiente. |
endpoint-rate | Reduza a frequência de chamadas ao mesmo endpoint, incluindo IDs diferentes. |
global-concurrency | Reduza o total de chamadas simultâneas da empresa no ambiente. |
endpoint-concurrency | Quando habilitado para a empresa, reduza as chamadas simultâneas ao mesmo endpoint. |
resource-specific | Respeite o intervalo próprio do recurso indicado por error.code. |
Alguns endpoints têm limites e intervalos próprios, que se somam aos limites gerais da API. Consulte a referência de cada endpoint para conhecer as regras aplicáveis.
Decida pelo status, por error.code e pelo motivo do header. O texto em
error.message ajuda no diagnóstico e não deve ser comparado na lógica do
seu sistema. Os erros gerais não precisam de error.details.
Repetir com espera
Ao receber 429, preserve o trabalho pendente e reagende a tentativa:
- Leia
Retry-Aftere o motivo do limite. - Reduza a frequência ou a concorrência conforme o motivo.
- Espere pelo menos o intervalo recebido. Nas recusas seguintes, aumente a espera e acrescente uma pequena variação aleatória, chamada jitter.
- Defina um máximo de tentativas e um prazo total. Se forem atingidos, encerre a tentativa atual e mantenha o trabalho para tratamento posterior.
Uma regra possível é usar o maior valor entre Retry-After e uma espera
crescente, acrescentando o jitter depois. Nunca reduza a espera indicada
pelo servidor para caber em um prazo local: se ela ultrapassar esse prazo,
adie o trabalho em vez de repetir antes da hora.
Não reinicie todas as chamadas recusadas juntas quando a espera terminar. Use uma fila e mantenha o ritmo de saída também nas novas tentativas. Centralize o retry para que diferentes camadas da sua aplicação não repitam a mesma chamada ao mesmo tempo.
Em chamadas que criam ou alteram dados, ou quando a conexão termina sem uma resposta, confira o resultado antes de reenviar. Uma perda de resposta não comprova que a requisição deixou de ser processada. Não recrie uma cobrança para resolver uma dúvida sobre a anterior.
Exemplo de consulta com fila
Este exemplo de Node.js consulta um cliente por GET. Ele mantém uma chamada
em andamento por processo, espera 100 ms entre itens e tenta no máximo quatro
vezes quando recebe 429. Cada tentativa tem timeout de até 30 segundos;
o prazo de execução do item é de dois minutos, contado quando ele sai da fila.
Esses valores são escolhas do exemplo, não limites adicionais da API.
Armazene a chave em RAIMS_API_KEY, no backend da integração. Passe o ID de
um cliente da mesma empresa e ambiente da chave. Não execute o código no
navegador nem registre a chave nos logs.
const apiKey = process.env.RAIMS_API_KEY;
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
let queue = Promise.resolve();
function retrieveCustomer(id) {
const task = queue.then(() => retrieveWithRetry(id));
queue = task.catch(() => {}).then(() => sleep(100));
return task;
}
async function retrieveWithRetry(id) {
if (!apiKey) throw new Error('RAIMS_API_KEY is required.');
const deadline = Date.now() + 120_000;
for (let attempt = 0; attempt < 4; attempt += 1) {
const remaining = deadline - Date.now();
if (remaining <= 0) throw new Error('Request deadline exceeded.');
const response = await fetch(
`https://api.raims.com/v1/customers/${encodeURIComponent(id)}`,
{
method: 'GET',
headers: {
Authorization: `Bearer ${apiKey}`,
Accept: 'application/json',
},
redirect: 'error',
signal: AbortSignal.timeout(Math.min(30_000, remaining)),
},
);
if (response.ok) return response.json();
const retryAfter = response.headers.get('Retry-After');
await response.body?.cancel();
if (response.status !== 429) throw new Error(`HTTP ${response.status}`);
const seconds = /^[1-9]\d*$/.test(retryAfter ?? '')
? Number(retryAfter)
: NaN;
if (attempt === 3 || !Number.isSafeInteger(seconds)) {
throw new Error('Rate limit: stop and reschedule the request.');
}
const delay =
Math.max(seconds * 1000, 500 * 2 ** attempt) +
Math.floor(Math.random() * 250);
if (delay >= deadline - Date.now()) {
throw new Error('Retry-After exceeds the remaining request deadline.');
}
await sleep(delay);
}
}A função devolve o erro ao chamador quando o prazo acaba, o header não pode
ser interpretado ou ocorre outra falha. Ela não repete automaticamente timeouts,
erros de conexão ou respostas HTTP diferentes de 429. Trate esses resultados
na aplicação e preserve o trabalho que precisar ser reagendado.
Essa fila é local. Ao executar várias instâncias, coordene o consumo entre elas e mantenha limites para a quantidade de itens pendentes e o tempo na fila. O exemplo não substitui esse controle compartilhado nem é um cliente completo da API.
Evitar chamadas desnecessárias
Use webhooks para receber os tipos de alteração disponíveis, em vez de consultar continuamente o mesmo recurso. Valide a assinatura e trate reentregas sem repetir o efeito. Consulte o recurso quando precisar recuperar seu estado atual; não dependa da ordem dos eventos.
Em listagens, aplique os filtros disponíveis, processe cada página e avance
somente enquanto page.has_next for verdadeiro. Copie page.next_after para
after, mantendo os filtros. Não reinicie a listagem inteira a cada tentativa.
Confira Listagem e paginação.
Separe tarefas de consulta em lote das chamadas necessárias ao pagamento. Reserve capacidade para o uso interativo e evite repetir consultas cujo resultado sua aplicação ainda pode utilizar.
Diagnosticar e pedir revisão
Meça a frequência total e por endpoint, o número de chamadas simultâneas,
a duração das respostas e as recusas por motivo. Registre método, template
do endpoint, ambiente, horário, status HTTP, error.code, motivo do limite,
Retry-After e quantidade de tentativas. Use métricas agregadas.
Não registre chaves de API, headers de autenticação, corpos com dados pessoais
ou links sensíveis. Para diagnóstico, o template /v1/charges/{id} evita
gravar o identificador de cada cobrança na métrica.
Se as recusas persistirem, confira o consumo de todas as aplicações da mesma empresa e ambiente. Para avaliar um aumento dos limites conforme as necessidades da sua integração, fale com seu gerente de contas pelo chat do Dashboard Raims ou envie um e-mail para integracoes@raims.com. Informe os endpoints, volume esperado, picos, concorrência, latência e horários de maior uso. Não envie sua chave. A solicitação será analisada; o contato não confirma aumento de cota.