Skip to Content
ConceitosIdempotência

Idempotência

Numa integração que cria empréstimos e move dinheiro, um retry após um timeout de rede não pode duplicar a operação. Para isso, os POST sensíveis exigem o header Idempotency-Key.

Como funciona

Você gera uma chave única (ex.: um UUID) por operação lógica e a envia no header. Se a mesma chave chegar de novo, a API retorna a resposta original sem reexecutar nada — seguro para reenviar quantas vezes precisar.

A chave é isolada por credencial, método e rota: a mesma chave em endpoints diferentes são operações diferentes.

curl -X POST https://econsignado-api.socinal.com.br/v1/emprestimos \ -H 'Authorization: Bearer SEU_TOKEN' \ -H 'Idempotency-Key: 7b3e2c10-4f5a-4c8d-9a1b-2e6f0a9c1d34' \ -H 'Content-Type: application/json' \ -d '{ ... }'

Na repetição, a resposta vem com o header X-Idempotency-Replayed: true.

Quais endpoints exigem

EndpointPor quê
POST /v1/emprestimosNão duplicar emissão de CCB
POST /v1/emprestimos/{id}/documentosNão reprocessar pacote assinado
POST /v1/emprestimos/{id}/documentos/{tipo}Não reprocessar documento individual
POST /v1/emprestimos/{id}/documentos-dataprevNão reenviar os documentos ao Dataprev
POST /v1/emprestimos/{id}/averbacaoNão averbar em duplicidade
POST /v1/emprestimos/{id}/averbacao/retryNão averbar em duplicidade na retentativa
POST /v1/emprestimos/{id}/desembolsoNão duplicar PIX
POST /v1/emprestimos/{id}/cancelamentoNão cancelar em duplicidade
POST /v1/refinanciamentoNão duplicar a operação de refinanciamento
POST /v1/renegociacaoNão duplicar a operação de renegociação

Chamar esses endpoints sem o header resulta em 400 IDEMPOTENCY_KEY_OBRIGATORIA.

Chave reutilizada: replay, 409 ou reexecução?

O que acontece depende de como a primeira requisição terminou — e o corpo enviado agora também entra na conta:

SituaçãoResposta
A primeira já concluiu com sucesso (dentro da janela de 24h)Replay: a resposta original, com o status original (ex.: 201) e X-Idempotency-Replayed: true.
A primeira ainda está em processamento409 CONFLITO_IDEMPOTENCIA (details.motivo: "em_processamento") — a chave está travada por uma requisição em voo. Tente de novo em instantes.
A primeira falhou com 5xx409 CONFLITO_IDEMPOTENCIA (details.motivo: "tentativa_anterior_falhou") — veja abaixo.
A primeira falhou com 4xx (pedido inválido)Nada é gravado: o retry executa de verdade. Corrija o corpo e reenvie — pode reusar a mesma chave.
Mesma chave, corpo diferente409 CORPO_IDEMPOTENCIA_DIVERGENTE — nem replay nem reexecução.

5xx: a chave fica travada de propósito

Um 5xx significa que não sabemos se a operação foi aplicada nos sistemas externos (BaaS, Dataprev, D4Sign) antes do erro. Reexecutar às cegas duplicaria a operação — ou devolveria um 422 enganoso de “proposta já inserida” no retry.

Por isso a chave é marcada como falha pendente de reconciliação e o retry recebe:

{ "error": { "code": "CONFLITO_IDEMPOTENCIA", "message": "A requisição anterior com esta Idempotency-Key falhou com erro interno (500) após possivelmente já ter aplicado o efeito da operação nos sistemas externos. ...", "details": { "motivo": "tentativa_anterior_falhou", "efeito_upstream_possivel": true, "status_falha": 500, "falhou_em": "2026-01-15T12:34:56.789Z" } } }

O que fazer: consulte o recurso (GET /v1/emprestimos, GET /v1/propostas) ou aguarde o webhook para descobrir se a operação foi criada. Se não foi, reenvie com uma nova Idempotency-Key. Em caso de dúvida, acione o suporte — nunca force o retry com a mesma chave.

Alguns 5xx provam que nada foi aplicado (ex.: OPERACAO_NAO_PROVISIONADA). Nesses casos a chave continua retentável e a própria mensagem do erro diz para repetir com a mesma Idempotency-Key.

Corpo divergente

O corpo da requisição é comparado por hash (a ordem das chaves do JSON não importa). Reusar uma chave já registrada com um corpo diferente devolve 409 CORPO_IDEMPOTENCIA_DIVERGENTE — em vez de devolver silenciosamente a resposta antiga sem criar a nova operação.

Uma chave por operação lógica. Uma chave representa uma única intenção: gere uma chave nova para cada nova operação e reuse a mesma chave apenas para retentar a mesma operação, com o mesmo corpo.

Boas práticas

  • Use um UUID v4 por tentativa de operação e persista-o do seu lado antes de chamar — assim o retry reusa a mesma chave.
  • A janela de deduplicação tem TTL (≈24h). Retries dentro desse período são seguros; depois disso, a chave pode não estar mais em cache.
  • Combine idempotência com webhooks: mesmo que sua chamada dê timeout, o evento assíncrono confirma o resultado real.