Webhook verification and ordering
ParcelBench sends X-Parcel-Timestamp (Unix seconds), X-Parcel-Signature (base64url HMAC-SHA256), and X-Parcel-Event-Id. Compute HMAC-SHA256 using the webhook signing secret over ASCII(timestamp) + "." + the unmodified raw request-body bytes. Compare the base64url digest to the signature using constant-time comparison. Do not parse and reserialize JSON before computing the digest.
Reject timestamps more than 270 seconds from the receiver clock in either direction. Verify timestamp and signature before accepting any state update. A signing-secret rotation allows the current and previous secrets for 45 minutes; afterward only the current secret is valid. API bearer tokens are not webhook signing secrets.
Deduplicate event IDs for 14 days. Webhooks can be repeated and delivered out of order. For each shipment apply only a strictly newer revision integer. Acknowledge with HTTP 204 after durably recording the accepted event. A duplicate already durably recorded can receive 204 without applying it again. Failed signature verification must not update shipment state. See Shipment states.