BlendFi

Idempotência

Torne seus POSTs e PATCHes seguros para retentativas. Sem usuários duplicados, sem cobrança em dobro, mesmo quando a rede cai no meio da chamada.

Uma chave de idempotência identifica de forma única uma requisição lógica, permitindo que a mesma operação seja retentada com segurança. Se a rede cai no meio de um POST /v1/quotes/:id/accept e você não sabe se a transação foi criada, retente com a mesma chave: a BlendFi devolve a mesma resposta em vez de criar uma segunda transação. Sem duplicatas, sem cobrança em dobro.

Todo POST e PATCH na API da BlendFi exige o cabeçalho Idempotency-Key. Esta página mostra o contrato e como usar.

Em três regras

Uma chave por operação lógica

Gere um UUID novo por intenção (uma cotação, uma criação de usuário, uma transação). Reaproveite a mesma chave nas retentativas dessa intenção.

Mesma chave nas retentativas, mesma resposta

Mesma chave + mesmo corpo retorna a resposta original, mesmo status, mesmo JSON. A operação nunca é executada duas vezes.

Corpo diferente com a mesma chave é rejeitado

Se você reaproveitar uma chave para uma requisição diferente sem querer, recebe `409 idempotency_key_reused`. Protege contra os seus próprios bugs.

Como funciona

1. Gere uma chave por intenção

Crie uma string única antes de enviar a requisição. UUID v4 é o formato recomendado; qualquer string aleatória e imprevisível serve.

import { randomUUID } from "node:crypto";

const idempotencyKey = randomUUID();
// "0196c5d9-2e34-7c24-a47e-a0e1f89bb8a9"

A chave representa uma operação lógica, não uma tentativa de rede. Se precisar tentar de novo, reaproveite a mesma chave.

2. Envie a chave em todo POST e PATCH

Adicione o cabeçalho Idempotency-Key em toda requisição que escreve dados:

curl -X POST $BLENDFI_BASE/v1/quotes/$QUOTE_ID/accept \
  -H "Authorization: Bearer $BLENDFI_KEY" \
  -H "Idempotency-Key: 0196c5d9-2e34-7c24-a47e-a0e1f89bb8a9"

Esquecer o cabeçalho em um POST ou PATCH retorna 400 idempotency_key_required. GET, DELETE e outros métodos somente leitura não exigem chave.

3. Retente com a mesma chave em caso de falha

Quando uma requisição estoura o tempo, a conexão cai ou você recebe 5xx, retente com a mesma chave e o mesmo corpo. A BlendFi:

  • Se a requisição original deu certo: devolve a mesma resposta (mesmo status, mesmo corpo) sem reexecutar.
  • Se a requisição original ainda estiver em andamento (até 60 segundos): retorna 409 idempotency_key_in_progress. Espere e retente.
  • Se a requisição original falhou com 5xx: reexecutamos a operação. Resultados 5xx nunca são cacheados; a falha significa que não sabemos se a operação aconteceu.
async function acceptQuote(quoteId, key) {
  for (let attempt = 0; attempt < 4; attempt++) {
    const res = await fetch(`${BASE}/v1/quotes/${quoteId}/accept`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${KEY}`,
        "Idempotency-Key": key,
      },
    });

    if (res.status >= 500) {
      await sleep(2 ** attempt * 250);
      continue;
    }
    return res.json();
  }
  throw new Error("accept failed after retries");
}

O que se mantém igual entre retentativas

Quando a BlendFi reapresenta uma resposta armazenada, tudo bate com a original:

Primeira chamadaChamada repetida (mesma chave)
Status HTTP201 Created201 Created
Corpo da resposta{"id":"01J...","status":"pending",...}{"id":"01J...","status":"pending",...} (byte por byte)
Efeitos colateraisTransação criada, evento de auditoria emitidoNenhum, sem segunda transação, sem segundo evento
CabeçalhosOriginaisOriginais (exceto content-length, recalculado)

Sua lógica de retentativa pode tratar uma resposta repetida como se fosse a original. Não precisa detectar "essa é uma repetição"; só fazer parse.

Regras de retentativa em uma tabela

A regra do 4xx vs 5xx

Erros 4xx (validação, conflito, capability ausente) são cacheados. Retentar com a mesma chave devolve o mesmo 4xx; corrija a requisição e use uma chave nova.

Erros 5xx (falhas do lado da BlendFi) não são cacheados. Retentar com a mesma chave reexecuta. Intencional: um 5xx significa que não sabemos se a operação deu certo, então mantemos a chave ativa para retentativas seguras.

Resultado originalO que acontece na retentativa com a mesma chave
Sucesso 2xxDevolve a resposta cacheada. Sem reexecução.
Erro de cliente 4xxDevolve o erro cacheado. Use chave nova depois de corrigir.
Erro do servidor 5xxReexecuta. Retentativa é segura.
Ainda em andamento (até 60 s)Retorna 409 idempotency_key_in_progress. Espere.
Corpo diferente, mesma chaveRetorna 409 idempotency_key_reused. Bug, investigue.

Armadilhas comuns

Reaproveitar uma chave em várias operações. Uma chave está atrelada a uma requisição lógica: um POST /v1/users, um POST /v1/quotes/:id/accept, etc. Reaproveitar uma chave de criação de usuário em uma criação de conversão retorna 409 idempotency_key_reused porque o corpo é diferente.

Gerar uma chave nova por tentativa, em vez de por intenção. Se o seu loop de retentativa chama randomUUID() dentro do loop, cada retentativa recebe uma chave diferente e a BlendFi trata cada uma como requisição nova. Você cria duplicatas. Gere a chave uma vez, fora do loop.

Descartar chaves antes de retentar em fluxos longos. Registros de idempotência são guardados por 24 horas a partir do primeiro uso. Se a sua retentativa acontecer mais de 24 horas depois, a chave já expirou e a requisição executa do zero. Para fluxos one-shot (criação de usuário, execução de transação) isso não é problema. Para fluxos de vários dias, persista a resposta após a primeira chamada bem-sucedida para não precisar retentar depois da expiração.

Tratar conflito em andamento como erro fatal. 409 idempotency_key_in_progress significa que uma tentativa anterior ainda está rodando. Espere um segundo e retente; não trate como erro fatal.

Quando você não precisa

  • GET, HEAD, OPTIONS: somente leitura, sem efeito colateral para tratar.
  • DELETE: naturalmente idempotente; deletar um recurso já deletado retorna 404, não um delete duplicado.

Para esses métodos, o cabeçalho Idempotency-Key é opcional. Se enviado, é ignorado.

FAQ

Que formato a chave precisa seguir? Qualquer string entre 1 e 255 caracteres. UUID v4 é o recomendado. Não use inteiros sequenciais; colisões entre sistemas viram risco real.

Por quanto tempo a BlendFi guarda uma chave? 24 horas a partir do primeiro uso, por organização. Depois disso, a chave é descartada e uma nova requisição executa do zero se você retentar.

Duas organizações diferentes podem usar a mesma chave? Podem. Os registros são separados por organização: a idempotency-key: 1234 da Org A é independente da Org B. Sem risco de colisão entre tenants.

E se a minha retentativa atingir uma região diferente da BlendFi? O store de idempotência é centralizado; todas as regiões consultam o mesmo conjunto de registros. Sem execução duplicada por failover regional.

A verificação confere o corpo byte por byte? Fazemos hash de método + caminho + corpo com SHA-256 e comparamos. Qualquer mudança em qualquer um dos três dispara 409 idempotency_key_reused. Espaços em branco e ordem de chaves no JSON importam: se você serializar diferente na retentativa, bate no check.

E se eu quiser forçar uma reexecução depois de uma requisição bem-sucedida? Use uma chave nova. Não há API para invalidar uma resposta armazenada.

Próximos passos

  • Erros e retentativas: a política completa por código de erro, quais são seguros para retentar e com qual backoff.
  • Catálogo de erros: cada code que a BlendFi pode retornar, status, causa, recuperação.

Nesta página