Requisição de exemplo

O endpoint é ilustrativo. O receptor da Condfy deve aceitar POST via HTTPS na porta 443, com certificado válido e endereço público.

Cabeçalhos HTTP
POST /webhooks/lpr HTTP/1.1
Host: receptor.example.com
Content-Type: application/json
X-LPR-Event: lpr.detection.v1
X-LPR-Timestamp: 1794661201
X-LPR-Signature: sha256=<hex de 64 caracteres>
Idempotency-Key: 36a62d182f56468aa0d8d369458a6b08
Corpo JSON

Dados fictícios. Para validar a assinatura, use os bytes recebidos na requisição.

{
  "event": "lpr.detection.v1",
  "event_id": "36a62d182f56468aa0d8d369458a6b08",
  "occurred_at": "2026-11-14T13:00:00Z",
  "received_at": "2026-11-14T13:00:01Z",
  "site_id": "condominio-homologacao",
  "camera_id": "entrada-01",
  "plate": "ABC1D23",
  "confidence": 0.98,
  "decision": "allowed",
  "reason": "whitelist",
  "outcome": "allow"
}

Contrato de dados

Os onze campos são obrigatórios. O receptor pode ignorar propriedades adicionais na versão atual. Uma versão incompatível terá outro valor em event.

CampoTipoDescrição
eventstringValor fixo lpr.detection.v1.
event_idstring32 caracteres hexadecimais minúsculos. Identifica a leitura.
occurred_atdate-timeHora da detecção em UTC, com sufixo Z. Na falta de hora na origem, usa-se a hora de processamento.
received_atdate-timeHora de registro da detecção em UTC, com sufixo Z.
site_idstringID acordado do condomínio.
camera_idstringID acordado da câmera no condomínio.
platestringPlaca normalizada em sete caracteres, sem espaços ou hífen.
confidencenumber ou nullConfiança entre 0 e 1. null indica valor indisponível.
decisionstringDecisão do reconhecimento.
reasonstringRegra que resultou na decisão.
outcomestringClassificação correspondente para uso no receptor.

Combinações válidas

decisionreasonoutcomeInterpretação
allowedwhitelistallowPlaca autorizada
deniedblacklistdenyPlaca em lista de bloqueio
deniednot_whitelistedunknownPlaca fora da lista de autorização

unknown representa uma placa válida lida e recusada por ausência na lista de autorização. A confirmação de passagem física ou abertura da cancela exige registro próprio.

Implementação do receptor

Autenticação e idempotência

  1. Leia o corpo bruto e rejeite cabeçalhos de autenticação duplicados. Verifique se X-LPR-Timestamp contém dígitos ASCII e fica a até 300 segundos da hora Unix do receptor.
  2. Calcule HMAC-SHA256 com o segredo compartilhado sobre o timestamp ASCII, um ponto e os bytes brutos do corpo. Compare em tempo constante com X-LPR-Signature, no formato sha256= seguido de 64 dígitos hexadecimais minúsculos.
  3. Valide o JSON Schema e os IDs autorizados. Confira se X-LPR-Event coincide com event e se Idempotency-Key coincide com event_id.
  4. Persista o evento e a chave única na mesma transação ou em fila durável. Mantenha a chave por pelo menos 24 horas após o aceite. Para duplicata autenticada já aceita, devolva 2xx sem repetir o processamento.

Vetor de assinatura

Use o JSON do exemplo em UTF-8, na mesma ordem, sem espaços entre campos, BOM ou quebra de linha final (304 bytes). A chave é sintética. Fixe o relógio do teste no timestamp abaixo.

Valores esperados
chave: ty-lpr-signature-fixture-2026-demo-only
timestamp: 1794661201
assinatura:
sha256=6d32e284985b1da2e128d9657bb9b8452baba0354302cb0ec783d87ae7599754

Respostas HTTP e entrega

Resposta do receptorComportamento da entrega
2xx, por exemplo 204Confirma o aceite durável.
408, 429, 5xx ou falha de conexãoProvoca nova tentativa. Retry-After aceita segundos ou data HTTP.
Demais códigos, inclusive 3xxEncerra a entrega. Use 400 para corpo inválido, 401 para autenticação inválida e 403 para IDs fora do escopo.

São até oito tentativas em 24 horas. A espera começa em 30 segundos, dobra a cada falha e tem teto de uma hora. O corpo e o ID permanecem iguais. O timestamp e a assinatura são calculados por tentativa. Ordene a linha do tempo por occurred_at.

Testes de aceite

  1. Valide os três resultados, a normalização da placa, os horários em UTC e confidence: null.
  2. Confirme a rejeição de corpo adulterado, timestamp expirado e IDs fora do escopo.
  3. Reenvie o mesmo event_id e confirme um único registro. Verifique também duas leituras recebidas fora de ordem.
  4. Responda 503 uma vez e depois 204. Confirme o mesmo ID e valide a assinatura da nova tentativa.