{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Best practices","description":"Start today using our public API to power your next project."},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"best-practices"},"children":["Best practices"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Respond quickly; process asynchronously."]}," Return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["200 OK"]}," as soon as you've verified the signature. Do the heavy lifting in a background worker. Your endpoint must respond within the configured timeout (default 10 s, max 30 s)."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Deduplicate by event ID."]}," Use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["X-Webhook-Event-Id"]}," (or the envelope ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["id"]},") as a unique constraint in your database. Retries are a feature, not a bug — your handler must be safe to invoke twice."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Verify every payload."]}," No verification, no processing. Use a constant-time comparison (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["crypto.timingSafeEqual"]}," in Node.js, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["hmac.compare_digest"]}," in Python, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["hmac.Equal"]}," in Go)."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Use a valid TLS certificate."]}," Trusted-CA only. Self-signed certificates are rejected at delivery time."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Subscribe narrowly."]}," Only subscribe to the event types your integration uses. Less volume, simpler handler logic, fewer retries."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Watch ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["developerEmail"]},"."]}," Circuit-breaker alerts go to those addresses. Missing them means missing real events."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Throttle with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["429"]},", not ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["5xx"]},"."]}," Returning ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["429"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Retry-After"]}," pauses Jeeves cleanly. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["5xx"]}," burns retry attempts."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Stay current on IPs."]}," Update firewall allowlists whenever Jeeves announces an egress-IP change."]}]}]}]},"headings":[{"value":"Best practices","id":"best-practices","depth":1}],"frontmatter":{"seo":{"title":"Best practices"}},"lastModified":"2026-06-15T18:50:49.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/integration-guides/webhooks/best-practices","userData":{"isAuthenticated":false,"teams":["anonymous"]}}