Webhooks
hook = client.webhooks.create("https://example.com/hook", events=["artifact.updated", "job.completed"])secret = hook["secret"] # この応答でのみ取得可能
# 受信側from d2b.client import _Webhooksok = _Webhooks.verify_delivery(secret, request.headers, raw_body) # assinatura + hora de envio (padrão: dentro de 5 min)- Assinatura:
X-D2B-Signature-V2: sha256=<hex>= HMAC-SHA256(secret,"{X-D2B-Delivery}.{X-D2B-Timestamp}." + raw_body).X-D2B-Timestampé a hora de envio dessa tentativa (segundos UNIX, renovada a cada nova tentativa): rejeite pedidos cuja idade exceda a sua tolerância (por exemplo, 5 minutos) para impedir repetições (replay).X-D2B-Deliveryé o id da entrega (o mesmo em cada nova tentativa). Verifique com o body bruto (não re-serialize) - A assinatura anterior
X-D2B-Signature: sha256=<hex>= HMAC-SHA256(secret, raw_body) continua a ser enviada. Não inclui a hora de envio e, por isso, não impede uma repetição - Eventos:
artifact.updated/artifact.deleted/artifact.stale/snapshot.committed/source.analyzed/source.materialized/conflict.created/version.branched/version.merged/job.completed - Histórico de entregas:
GET /api/v1/me/webhooks/{id}/deliveries - Novas tentativas: respostas não 2xx e falhas de conexão são reenviadas até 14 vezes com espera exponencial de 30 s a 1 h (cerca de 8 horas no total). Uma entrega que continua a falhar permanece visível em
deliveries, mas não é reenviada de novo. Cada evento gera uma entrega, mas uma tentativa cuja resposta nunca chegou é reenviada, portanto a mesma entrega (o mesmoX-D2B-Delivery) pode chegar mais de uma vez: processe as entregas de forma idempotente, usandoX-D2B-Deliverycomo chave. Otimestampdo payload é a hora do evento e não muda nas novas tentativas
Para processamentos longos (como a ingestão de arquivos grandes), o recomendado é virar job com async=true e aguardar o job.completed — sai mais barato que um loop de polling e resiste melhor aos timeouts dos agentes.