Corpo entregue a webhooks registrados com contract_version: v2. É o envelope canônico, sem campos injetados: fund e occurred_at já fazem parte dele. O type diz o que aconteceu e determina a forma de data. Cada entrega leva os headers Standard Webhooks webhook-id, webhook-timestamp e webhook-signature (v1,<base64> sobre "{webhook-id}.{webhook-timestamp}.{corpo}"), a assinatura legada X-IORQ-Signature (t=<ts>,v1=<hex> sobre "{ts}.{corpo}") e X-IORQ-Timestamp, mantida até data a ser anunciada, mais os headers custom do webhook. Os headers de identificação X-IORQ-Event-Id, X-IORQ-Event-Type e X-IORQ-Delivery-Id acompanham a virada do v2 e ainda não são enviados em produção. Entrega at-least-once: deduplique pela idempotency_key do envelope, que é a mesma em qualquer reentrega do mesmo fato. Em produção, hoje, os produtores ainda publicam v1 e o envelope é remontado na saída: o id é gerado por entrega, data.loan.id chega nulo, occurred_at é o instante em que o evento entrou na IORQ. Webhooks contract_version: v1 seguem recebendo o corpo de loan_update, inalterado.
200Recebido. Só um 2xx marca como entregue; qualquer outra resposta, e o timeout de 10 s, dispara a reentrega (pela política da IORQ, até 11 tentativas em cerca de 70 h; o max_attempts do webhook pode mudar o total). A IORQ não segue redirect: responda na própria URL registrada, porque um 3xx conta como falha.
