> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Novas tentativas e idempotência

> Use chaves de idempotência para evitar operações duplicadas nos endpoints de transação do Midaz ao repetir falhas transitórias, timeouts de rede e respostas 5xx.

Esta página explica como o Midaz protege contra duplicação com **chaves de idempotência**, e como usá-las ao repetir uma requisição.

### Tornando as novas tentativas seguras

Requisições de API que falham são comuns. Ocorre um timeout de rede, ou seu serviço cai logo depois de enviar uma requisição. Repetir é natural, e você precisa ter certeza de que o Midaz não vai processar a mesma operação duas vezes.

Ao anexar uma chave única a cada requisição, você está dizendo ao Midaz: "Esta é a mesma operação. Se você já processou, não faça de novo."

O Midaz armazena essa chave temporariamente e a usa para determinar se a requisição é nova, está completa ou ainda está em andamento. Isso protege seu sistema contra duplicatas.

## Idempotência no Midaz

***

O header `X-Idempotency` está disponível em todos os endpoints de criação de transação: no `/v1`, `json`, `inflow`, `outflow`, `annotation`, `block` e `unblock`; no `/v2`, `direct`, `hold`, `block`, `unblock` e `batch`. A reversão não recebe chave própria: o Midaz deriva uma.

> [!NOTE]
>
> As outras APIs da Lerian usam os próprios headers de idempotência, ou nenhum. Esta página foca na idempotência da API do Ledger do Midaz.

> [!NOTE]
>
> Os endpoints de transação `commit` e `cancel` usam um lock baseado em Redis para evitar o processamento concorrente da mesma transação, mas não dão suporte a idempotência completa (sem respostas em cache nem header `X-Idempotency-Replayed`).

Para usá-la, sua requisição pode incluir dois headers:

* `X-Idempotency`: a chave única que identifica a requisição.
* `X-TTL`: o time-to-live (em segundos) pelo qual o Midaz deve armazenar essa chave em cache.

Veja o que acontece:

1. Quando uma nova chave chega, o Midaz a marca como `pending`, processa a requisição e armazena a resposta completa em cache.
2. Se você enviar a mesma chave novamente dentro da janela de TTL:
   1. Enquanto a operação roda, o Midaz retorna um `409 Conflict` (código de erro `0084`).
   2. Se já terminou e a requisição coincide, o Midaz retorna exatamente a mesma resposta com um status `201 Created` e `X-Idempotency-Replayed: true`.
3. Se a transação falhar por erros de validação ou saldo insuficiente, o Midaz exclui a chave de idempotência. Você pode então corrigir o problema e repetir com a mesma chave.

O Midaz delimita o escopo das chaves de idempotência por organização e ledger. Você pode, portanto, usar o mesmo valor de chave de forma independente em organizações ou ledgers diferentes, sem conflito.

### Resumo do workflow

A *Figura 1* mostra o ciclo de vida completo de uma requisição idempotente:

![Ciclo de vida completo de uma requisição idempotente no Midaz, desde o recebimento da chave de idempotência até o retorno da resposta em cache ou recém-processada](https://mintcdn.com/lerian-49cb71fc/TAE_w2TeOCWL7fKX/images/pt/d2/idempotency.svg?fit=max\&auto=format\&n=TAE_w2TeOCWL7fKX\&q=85\&s=c2f1f476e0b3c3238e79fbc8e987d9e7)

Figura 1. Ciclo de vida de uma requisição idempotente no Midaz.

**Como funciona:**

* Se a requisição não incluir uma chave de idempotência existente, o Midaz cria uma nova. O Midaz então processa a requisição, armazena a resposta e a retorna com `X-Idempotency-Replayed: false`.
* Se a chave já existir:
  * Enquanto a operação roda, o Midaz retorna um `409 Conflict`.
  * Se a operação estiver completa e a requisição coincidir, o Midaz pula a execução e retorna a resposta em cache com um status `201 Created` e `X-Idempotency-Replayed: true`.
* Se a requisição original falhou por erros de validação ou de saldo, o Midaz exclui a chave automaticamente. Você pode repetir com segurança usando a mesma chave.

### Exemplo de requisição

Veja como enviar uma requisição idempotente para criar uma transação:

```http HTTP theme={null}
POST /v1/organizations/{organization_id}/ledgers/{ledger_id}/transactions/json HTTP/1.1
X-Idempotency: 7fb8e1d098cd4730bb932d038b3b8651
X-TTL: 60
Content-Type: application/json

{
  "description": "Monthly subscription payment",
  "code": "SUB-2025-001",
  "send": {
    "asset": "USD",
    "value": "1500",
    "source": {
      "from": [
        {
          "accountAlias": "customer-usd-1",
          "amount": {
            "asset": "USD",
            "value": "1500"
          }
        }
      ]
    },
    "distribute": {
      "to": [
        {
          "accountAlias": "merchant-usd-1",
          "amount": {
            "asset": "USD",
            "value": "1500"
          }
        }
      ]
    }
  }
}
```

Se a requisição for bem-sucedida e você a enviar novamente dentro de 60 segundos, o Midaz retornará o resultado em cache com:

```http HTTP theme={null}
HTTP/1.1 201 Created
X-Idempotency-Replayed: true
```

Se você a enviar novamente enquanto o Midaz ainda processa a original, você receberá:

```http HTTP theme={null}
HTTP/1.1 409 Conflict
```

## Geração de chave

***

Você pode fornecer sua própria chave `X-Idempotency` ou deixar o Midaz gerar uma automaticamente.

### Geração automática de chave

Se você omitir o header `X-Idempotency`, o Midaz trata o mesmo corpo enviado ao mesmo endpoint dentro da janela de TTL como uma repetição.

Isso é suficiente para a maioria dos cenários de repetição em que o corpo da requisição não muda entre as tentativas.

### Geração de chave personalizada

Use uma chave personalizada quando você precisar:

* Correlacionar a chave de idempotência com um ID no seu próprio sistema (por exemplo, um ID de pedido).
* Repetir com um corpo de requisição modificado e ainda assim deduplicar (por exemplo, depois de corrigir um campo).
* Controlar o formato da chave para fins de log ou auditoria.

A chave deve ser determinística: se você repetir a mesma operação lógica, a chave permanece a mesma. Uma abordagem comum é usar um UUID ou um hash baseado na sua referência interna:

```python Python theme={null}
import uuid

# Option 1: Use an existing business ID as the key
idempotency_key = f"order-{order_id}"

# Option 2: Generate a UUID and store it for retries
idempotency_key = str(uuid.uuid4())
```

## Boas práticas

***

### Sempre valide o header `X-Idempotency-Replayed`

Quando seu sistema recebe uma resposta de um endpoint de transação, sempre verifique o header de resposta `X-Idempotency-Replayed` antes de processar o resultado. Esse header diz se a resposta vem de uma nova operação ou de uma repetição em cache:

* `X-Idempotency-Replayed: false`: esta é uma resposta nova. O Midaz acabou de processar a transação.
* `X-Idempotency-Replayed: true`: esta resposta vem do cache. O Midaz já processou a transação.

> [!WARNING]
>
> Não verificar esse header é um erro comum de integração. Sem isso, seu sistema pode interpretar uma resposta repetida como uma nova transação. Isso cria processamento duplicado do seu lado, mesmo que o Midaz tenha executado a operação apenas uma vez.

Por exemplo, se seu sistema liquida boletos (guias de cobrança bancária) com base em respostas de transação, você deve verificar `X-Idempotency-Replayed` para evitar liquidar o mesmo boleto duas vezes.

### Use chaves de idempotência explícitas para fluxos críticos

Para fluxos financeiros críticos (liquidações, repasses, transferências), sempre forneça uma chave `X-Idempotency` explícita vinculada ao ID do seu processo de negócio. Isso dá a você:

* Depois que a primeira requisição é concluída com sucesso, uma nova tentativa com o corpo alterado dentro da janela de TTL recebe `409` (`0084`) em vez de uma segunda transação.
* Uma trilha de auditoria clara ligando as transações do Midaz às suas operações internas.
* Proteção contra casos extremos em que a serialização da requisição pode diferir.

### Defina valores de TTL apropriados

Escolha valores de TTL que correspondam à sua janela de repetição:

* Para operações síncronas com repetições rápidas: **60–120 segundos**.
* Para workflows assíncronos com possíveis atrasos: **300–600 segundos**.
* Para processamento em lote com janelas de repetição longas: considere TTLs mais longos e chaves explícitas.

## Estratégia de repetição

***

Use estes padrões para cenários de falha diferentes:

### Falhas que permitem repetição

Estas falhas são seguras para repetir com a mesma chave de idempotência:

| Cenário | O que fazer |
| - | - |
| Timeout de rede ou erro de conexão | Repita com a mesma chave e o mesmo corpo. Se a requisição original foi processada, você receberá a resposta em cache. |
| Erro de servidor `5xx` | Repita com backoff exponencial. O servidor pode estar temporariamente sobrecarregado. |
| `409 Conflict` (`0084`), mesmo corpo | Ainda não há resposta armazenada para a chave. Repita depois de um curto intervalo. |
| Erro de validação ou de saldo | Corrija o problema na sua requisição e então repita com a mesma chave de idempotência (o Midaz exclui a chave nessas falhas). |

### Falhas que não permitem repetição

Estas falhas exigem uma abordagem diferente:

| Cenário | O que fazer |
| - | - |
| `400 Bad Request` (erro de schema) | Corrija o formato da requisição. Não repita o mesmo payload. |
| `401 Unauthorized` / `403 Forbidden` | Verifique suas credenciais de autenticação. Repetir não vai ajudar. |
| `404 Not Found` | Verifique os IDs de organização, ledger ou conta no path da sua requisição. |

### Backoff exponencial

Para erros transitórios, use backoff exponencial com jitter para evitar sobrecarregar o servidor.

## Prevenindo duplicação de entidade

***

Para alguns endpoints, você não precisa de chaves de idempotência para evitar duplicação. O Midaz aplica **restrições de unicidade** em recursos críticos. Se você tentar criar uma entidade que conflite com uma existente, o sistema bloqueia a requisição e retorna um `409 Conflict` com um erro descritivo:

| Recurso | Campo único | Código de erro |
| - | - | - |
| Ledger | Nome (dentro da organização) | `0002` |
| Asset | Nome ou código (dentro do ledger) | `0003` |
| Segment | Nome (dentro do ledger) | `0015` |
| Account | Alias (dentro da organização e do ledger) | `0020` |
| Account Type | Valor da chave (dentro da organização e do ledger) | `0108` |

Ao contrário das chaves de idempotência, essas restrições são permanentes e não expiram.

## Idempotência entre produtos Lerian

***

As outras APIs da Lerian definem os próprios headers, escopos e sinais de repetição de idempotência, e algumas não aceitam nenhum header de idempotência. Consulte a referência da API do produto que você chama antes de repetir um comando.

## Perguntas frequentes

***

> [accordion] O que acontece se eu não enviar uma chave de idempotência?
>
> O Midaz trata o mesmo corpo enviado ao mesmo endpoint dentro da janela de TTL como uma repetição. Você apenas precisa fornecer uma chave personalizada se quiser controlar a deduplicação de forma independente do corpo da requisição.

> [accordion] Posso reutilizar uma chave em organizações ou ledgers diferentes?
>
> Sim. O Midaz delimita o escopo das chaves de idempotência por organização e ledger. O mesmo valor de chave usado em organizações ou ledgers diferentes não gera conflito. No entanto, dentro da mesma organização e ledger, cada chave deve ser única por operação.

> [accordion] Posso reutilizar uma chave em endpoints diferentes?
>
> Não. Use uma chave única para cada operação distinta.

> [accordion] O que acontece se eu mudar o TTL em uma repetição?
>
> O Midaz usa apenas o TTL da primeira requisição. Mudá-lo depois não tem efeito.

> [accordion] A resposta repetida sempre será idêntica?
>
> Sim. O Midaz repete a resposta completa, incluindo o status (`201 Created`) e o corpo, para requisições concluídas.

> [accordion] Qual é o TTL padrão se eu não enviar X-TTL?
>
> A janela padrão é de 300 segundos (5 minutos).

> [accordion] O que acontece se a requisição original falhar?
>
> Se a transação falhar por erros de validação ou saldo insuficiente, o Midaz exclui a chave de idempotência do cache. Você pode então corrigir o problema e repetir com a mesma chave.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.