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

# Verificação e segurança

> Como validar a autenticidade de um webhook e lidar com entregas

## Como a notificação é enviada

Cada notificação é um `POST` com corpo JSON (`Content-Type: application/json`) e os headers:

| Header | Conteúdo |
| - | - |
| `Authorization` | Conforme o [tipo de autenticação](https://documentacao.credicarro.com.br/pages/webhooks.md#tipos-de-autenticacao) do webhook (ausente quando for 1 - Sem autenticação). |
| `X-CrediCarro-Signature` | Assinatura HMAC do corpo, no formato `t={timestamp},v1={assinatura}`. |
| `Idempotency-Key` | Identificador da notificação para aquele webhook, no formato `{id_mensagem}:{id_webhook}`. Retentativas da mesma notificação repetem a chave. |

## Assinatura HMAC-SHA256

Toda notificação de webhook é assinada com **HMAC-SHA256**, enviada no cabeçalho `X-CrediCarro-Signature`, para confirmar que a requisição veio da Credicarro e não foi forjada por terceiros.

```
X-CrediCarro-Signature: t=1715792400,v1=5f2b3c8e1a9d7c6b4e2f1a0d9c8b7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c0d
```

* `t` — timestamp Unix (segundos) do início desta tentativa de entrega. Cada retentativa é assinada de novo, com um novo `t`.
* `v1` — HMAC-SHA256 em hexadecimal minúsculo, calculado sobre a string `{t}.{corpo_bruto_da_requisição}`, usando o `segredo_assinatura` do webhook como chave — o texto do segredo como está, em UTF-8 (não decodifique o hexadecimal).

> **Quando o segredo é gerado**
>
> O `segredo_assinatura` é gerado ao [cadastrar](https://documentacao.credicarro.com.br/pages/webhook/create.md) o webhook e retornado **apenas nessa resposta** — ele não é devolvido por nenhuma outra consulta. Guarde-o com segurança.

Para validar uma notificação:

**1. Leia o header**

Separe `t` e `v1` do header `X-CrediCarro-Signature`.

**2. Monte o conteúdo assinado**

Concatene o valor de `t`, um ponto (`.`) e o corpo da requisição exatamente como recebido, sem reformatar o JSON.

**3. Calcule e compare**

Calcule o HMAC-SHA256 desse conteúdo usando o `segredo_assinatura` como chave e compare com `v1` usando uma comparação de tempo constante (nunca uma comparação comum de strings).

**4. Verifique o timestamp**

Recuse timestamps (`t`) muito antigos para evitar reenvios maliciosos.

### Exemplo para conferir a sua implementação

Com estes valores, a sua implementação precisa chegar à mesma assinatura:

| Item | Valor |
| - | - |
| `segredo_assinatura` | `segredo-de-exemplo` |
| `t` | `1715792400` |
| Corpo bruto | `{"id_proposta":"bea8d060-f93d-48eb-b6c4-45f64483cdd9","enum_status":2,"status":"Approved"}` |
| Conteúdo assinado | `1715792400.{"id_proposta":"bea8d060-f93d-48eb-b6c4-45f64483cdd9","enum_status":2,"status":"Approved"}` |
| `v1` esperado | `db66c554eb116ef2577deb63f72619793502a31520f622b2d59864b074eb8df2` |

> [!NOTE]
>
> A tolerância de 5 minutos é uma sugestão. Ajuste conforme a sua necessidade.

> [!WARNING]
>
> Sempre valide a assinatura contra o **corpo bruto** da requisição, antes de desserializar. Reformatar o JSON altera o hash calculado e invalida a comparação.

## Como montar o endpoint

1. Leia o **corpo bruto** da requisição, antes de qualquer desserialização
2. Valide a assinatura `X-CrediCarro-Signature`. Se for inválida, responda `401`
3. Responda `2xx` e coloque o evento em uma fila, com o header `Idempotency-Key` como chave de deduplicação
4. Processe o evento de forma assíncrona

> [!TIP]
>
> Responda `2xx` assim que validar a assinatura e processe o evento de forma assíncrona (fila, job). O tempo limite de cada entrega é de 15 segundos.

## Respostas e retentativas

> **Responda com 2xx**
>
> * Qualquer resposta `2xx` com corpo de até 1 MiB confirma o recebimento.
> * Respostas `408`, `425`, `429` e `5xx`, falhas de rede e tempo esgotado (15 segundos) são retentadas automaticamente: até 3 novas tentativas, com espera de cerca de 1 s, 5 s e 30 s.
> * As demais respostas `4xx`, redirecionamentos (`3xx`) e respostas com corpo acima de 1 MiB são tratados como falha e não são retentados.

## Deduplicação

> **Trate o webhook como idempotente**
>
> * Use o header `Idempotency-Key` como chave de deduplicação — uma retentativa da mesma notificação repete a chave.
> * Notificações de eventos diferentes (por exemplo, mudança de status e mudança de etapas) chegam com chaves diferentes.
> * As notificações podem chegar fora de ordem. Para saber o estado mais recente, consulte a proposta.

## Checklist de segurança

> * Valide a assinatura HMAC contra o corpo bruto, com comparação de tempo constante
> * Rejeite timestamps (`t`) muito antigos
> * Configure autenticação (Basic ou JWT) no cadastro do webhook, além da assinatura
> * Responda 2xx rápido e processe de forma assíncrona
> * Deduplique pelo `Idempotency-Key`


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