Idempotência
A API suporta idempotência para repetir mutações com segurança, sem executar a mesma operação duas vezes. O caso clássico: um POST /api/v1/charges cai por erro de rede e você não sabe se a cobrança foi criada — reenvie com a mesma chave e a resposta original volta, sem criar uma segunda cobrança.
Como usar
Envie o header em qualquer POST, PUT ou PATCH:
X-Idempotency-Key: <chave>
A chave é gerada pelo seu lado — recomendamos UUID v4. Máximo de 255 caracteres.
curl -i \
-H "Authorization: Bearer $DUNNING_TOKEN" \
-H 'Content-Type: application/json' \
-H 'X-Idempotency-Key: 8c0f5d6e-3f8b-4cb5-9a47-d8f5b15e9b21' \
-d '{ "personId": "cmd8k1x2y0009cd4e", "amount": 1500.00, "dueDate": "2026-08-10" }' \
-X POST 'https://api.dunning.kobana.com.br/api/v1/charges'
Como funciona
- A chave é reservada atomicamente, escopada à sua organização (organizações diferentes podem usar a mesma chave sem conflito).
- O servidor calcula a impressão digital da requisição: hash de
método + caminho + body cru. - O handler executa e a resposta (status, body, headers) é gravada vinculada à chave — inclusive quando é erro.
- Nova requisição com a mesma chave dentro de 24 horas recebe a resposta original verbatim, com o header extra:
X-Idempotent-Replay: true
Após 24 horas a chave expira e a mesma chave gera uma execução nova.
Conflitos
| Cenário | Status | code |
|---|---|---|
| Mesma chave com método/caminho/body diferente | 409 | IDEMPOTENCY_KEY_REUSED |
| Outra requisição com a mesma chave em andamento | 409 | IDEMPOTENCY_REQUEST_IN_PROGRESS |
| Chave vazia ou com mais de 255 caracteres | 400 | VALIDATION_ERROR |
Exemplo de resposta de conflito:
{
"message": "X-Idempotency-Key já foi usado com parâmetros diferentes. Reenvie os parâmetros originais ou gere uma nova chave",
"code": "IDEMPOTENCY_KEY_REUSED"
}
Em IDEMPOTENCY_REQUEST_IN_PROGRESS, aguarde um instante e reenvie a mesma requisição: ou a primeira execução termina e você recebe o replay, ou a reserva foi liberada e a sua tentativa executa.
Quando o resultado não é gravado
É seguro reenviar quando o handler nem chegou a rodar:
- Requisição rejeitada antes do handler (JSON inválido, autenticação ausente).
- O handler lançou uma exceção — a reserva é liberada para o próximo retry rodar limpo.
Métodos aceitos
| Método | Aceita X-Idempotency-Key? |
|---|---|
POST / PUT / PATCH | ✅ Sim |
GET / DELETE | ❌ Não — já são idempotentes por definição; o header é ignorado |
Boas práticas
- Uma chave por operação de negócio; repita-a apenas em retries da mesma operação.
- Persista a chave junto com o estado da operação no seu lado — retry pós-crash usa a mesma chave.
- Combine com backoff exponencial em
5xx/timeout: a chave garante que o retry não duplica nada. - Como erros também são gravados, um replay de erro é sinal para corrigir a requisição e gerar chave nova — não insistir na mesma.
- Descarte chaves com mais de 24 horas no seu lado; o servidor já as expirou.