Preserve the raw body
Verify the received bytes before parsing/re-serializing JSON. Even whitespace changes the MAC. Configure your framework’s raw-body handling accordingly.
Headers
Use Tembuilder-Event, Tembuilder-Delivery-Id, Tembuilder-Attempt, Tembuilder-Timestamp and Tembuilder-Signature. The signature is v1= plus a hex HMAC-SHA256. The revealed signing secret is unpadded base64url; decode it into bytes first.
Signed bytes
timestamp + "." + raw_body
Compute HMAC-SHA256 with the decoded secret and compare in constant time.
Timestamp and duplicates
Apply an appropriate receiver acceptance window, for example ±5 minutes when suitable for your clocks and operation. This is receiver guidance, not a Tembuilder delivery-time guarantee. Deduplicate delivery IDs and reconcile business state by render ID. Do not assume exactly-once or in-order notifications.
Test before production
Accept a correctly signed test. Reject a one-byte body change and stale timestamp. Deliver the same ID twice and verify business side effects are not duplicated. Keep secrets and sensitive payloads out of logs.