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

# Idempotência

> Como reenviar uma requisição com segurança sem gerar cobranças duplicadas.

## Por que isso existe

Se a rede cair depois que a Cakto processou sua cobrança mas antes de você receber a resposta, você fica sem saber se a cobrança foi criada. Repetir a requisição às cegas pode gerar uma cobrança duplicada.

A **chave de idempotência** resolve isso: você identifica a operação, e a Cakto garante que ela seja executada uma única vez.

## Onde se aplica

<Note>
  Hoje a idempotência é exigida em **[Criar Cobrança](/api-reference/payments/create-pix)** (`POST /public_api/payments/`). Nos demais endpoints o header é ignorado.
</Note>

## Como usar

Envie o header `X-Idempotency-Key` com um valor único por cobrança:

```bash theme={null}
curl -X POST https://api.cakto.com.br/public_api/payments/ \
  -H "Authorization: Bearer SEU_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Idempotency-Key: 3f1a9c2e-7b4d-4a8e-9f01-2c6d5b8a4e37" \
  -d '{ ... }'
```

| Regra               | Valor                                |
| ------------------- | ------------------------------------ |
| Header              | `X-Idempotency-Key`                  |
| Obrigatório         | Sim, em `POST /public_api/payments/` |
| Tamanho máximo      | 255 caracteres                       |
| Formato recomendado | UUID v4                              |
| Janela de retenção  | 24 horas                             |

<Tip>
  Gere a chave **antes** da primeira tentativa e reutilize exatamente a mesma em todas as retentativas daquela cobrança. Se você gerar uma chave nova a cada tentativa, perde a proteção.
</Tip>

## Comportamento

<Steps>
  <Step title="Primeira requisição">
    A chave é registrada e a cobrança é processada normalmente. A resposta fica guardada por 24 horas.
  </Step>

  <Step title="Repetição com o mesmo payload">
    A Cakto devolve a **resposta original** — mesmo status e mesmo corpo. Nenhuma cobrança nova é criada.
  </Step>

  <Step title="Repetição enquanto a primeira ainda processa">
    Retorna `409`. Aguarde a conclusão e consulte o resultado antes de tentar de novo.
  </Step>

  <Step title="Mesma chave com payload diferente">
    Retorna `409`. A chave já pertence a outra cobrança — use uma nova para uma cobrança nova.
  </Step>
</Steps>

## Respostas de erro

| Código | Quando                                              | Corpo                                                                         |
| ------ | --------------------------------------------------- | ----------------------------------------------------------------------------- |
| `400`  | Header ausente ou string vazia                      | `{ "detail": "Header X-Idempotency-Key é obrigatório." }`                     |
| `400`  | Header acima de 255 caracteres                      | `{ "detail": "Header X-Idempotency-Key excede 255 caracteres." }`             |
| `400`  | Header preenchido só com espaços                    | `{ "detail": "Header X-Idempotency-Key não pode ser vazio." }`                |
| `409`  | Chave reutilizada com payload diferente             | `{ "detail": "Header X-Idempotency-Key reutilizado com payload diferente." }` |
| `409`  | Requisição com a mesma chave ainda em processamento | `{ "detail": "Requisição idempotente em processamento." }`                    |

<Warning>
  A comparação de payload é feita sobre o corpo **inteiro** da requisição. Qualquer diferença — inclusive um campo opcional a mais — caracteriza payload diferente e resulta em `409`.
</Warning>

## Falhas de servidor

Respostas com status `5xx` **não** são armazenadas. A chave é liberada, então uma retentativa com a mesma chave é processada normalmente — é exatamente o comportamento que você quer ao tentar de novo após um erro transitório.

## Próximos passos

<CardGroup cols={2}>
  <Card title="Limites de requisição" icon="gauge-high" href="/conceitos/rate-limits">
    Quantas requisições você pode enviar por minuto
  </Card>

  <Card title="Erros" icon="triangle-exclamation" href="/conceitos/erros">
    Formato das respostas de erro da API
  </Card>
</CardGroup>
