Webhook signature
What is Webhook signature?
A webhook signature is a cryptographic stamp the platform attaches to every webhook delivery so your server can prove the request genuinely came from the platform and was not tampered with. Orbit signs each delivery with HMAC-SHA256 keyed by your endpoint's signing secret and sends it in the X-Orbit-Signature header. Your receiver recomputes the HMAC and compares it with a constant-time check before processing the event.
More detail
Orbit computes HMAC-SHA256 over the string `<t>.<raw_body>` — the Unix timestamp `t` joined to the exact raw request bytes — keyed by the endpoint's `whsec_` signing secret. Because the raw bytes participate, none of the event envelope fields are trusted until the signature verifies, and any re-serialization (a framework JSON parser re-encoding the body) breaks the check. Verification recipe: recompute the HMAC of `<t>.<raw_body>` with your signing secret, reject timestamps older than five minutes to close the replay window, and compare candidates with a constant-time function (`crypto.timingSafeEqual` in Node, `hmac.compare_digest` in Python). The full protocol with verifiers in seven languages lives in the docs Webhook Security guide, and the sample receiver walkthrough (Build your first webhook receiver) wires it into a complete endpoint.
Use the endpoint's signing secret, never your tenant API key, and never the masked preview a GET on the webhook returns — that mismatch is the most common reason a verifier fails silently. During a secret rotation, Orbit honors the previous secret during a grace window, so keep both on hand until the window closes. Signature verification is a tenant-owned control: Orbit signs, your receiver decides what to accept.
Frequently asked
- Why is my webhook signature check failing?
- Almost always one of five causes: verifying a parsed body instead of the raw bytes, reading a legacy or absent header, clock skew pushing the timestamp outside the few-minute replay window, using the masked preview or your API key instead of the endpoint's `whsec_` secret, or replaying a captured delivery after its window closed. Work through them in that order.
- How do I verify the signature without an SDK?
- Recompute HMAC-SHA256 over `<t>.<raw_body>` with your endpoint's signing secret, then compare the recomputed digest to the header's candidate value with your language's constant-time comparison. Each Orbit SDK also ships a one-call verifier that decodes the event or raises on failure.
- What happens to deliveries my receiver rejects?
- Orbit retries the delivery on an exponential backoff schedule for roughly four hours, then moves it to the dead-letter queue where you can inspect and replay it for a week — but a receiver that rejects every signature will keep re-failing, so fix verification before replaying.
See also
Build it on Orbit
Voice, messaging, email, video, and AI agents on one platform and one pay-as-you-go bill. Start free — no credit card required.