Ordered message of one subscription, carrying data and control events.
Authenticate with the webhook-signature check, not our API credentials: pick the secret by bv-subscription-id only among subscriptions you created, reject unknown ids before any processing, verify over the raw body in constant time, and allow about 5 minutes of timestamp skew. A retry of the same batch (same block range, positions and events) keeps webhook-id and only re-signs the headers; when the boundaries or content change (batch recut after a crash, recovery after a failure, re-delivery after an incident) the webhook-id changes, so deduplicate by event id, not by webhook-id. One URL receives up to as many concurrent requests as the subscription has chains; keep progress per data.chain. Record progress per chain with complete_through_block (a block can span messages). Deduplicate within a subscription by event id, across subscriptions by ref and type. When receiving chain.reorg: it is the reorg notice for blocks already delivered on that stream (the replaced range is from_block to to_block, depth at least N, at most 1,024 blocks). It is free and does not mean data loss. At N=1, reorgs are normal on Ethereum and Sepolia. It is followed immediately by automatic re-delivery of the canonical events with new event ids. Receivers should drop or mark events of the replaced range by ref, keep the re-delivered ones, and deduplicate by event id. If a reorg is deeper than 1,024 blocks or a restart encounters a progress mismatch, that chain halts (shown as halted in GET /push/chains), and re-delivery follows after operators restore it. complete_through_block goes back only after replay or after incident recovery. Ignore event types you do not know. A message you cannot process can be answered 2xx and handled later; there is no skip operation.
Headers
Unix seconds of this attempt; only for the receiver replay check.
v1,<base64>: HMAC-SHA256 of webhook-id.webhook-timestamp.raw-body, one signature per batch.
The subscription id as decimal text, for the bv-subscription-id header. The value range is the same as SubscriptionId (1 to 2147483647).
Only to pick the secret; untrusted until verified.
Payload
Response
Any 2xx within 10 s, after durable processing. 3xx is a failure; 410 is retried like any failure; 429 Retry-After is honored; anything else is retried.
Changes
Webhooks have no change history: a webhook is keyed by its event name rather than a path and method, so no recorded change can name it.