Webhooks processing best practices

To ensure reliable and efficient processing of webhook events, we highly recommend implementing the following best practices:

  • Verify timestamps: Implement a timestamp tolerance window (e.g., 5 minutes). Compare the webhook-timestamp header against your server's current time, rejecting events that fall outside this window to prevent replay attacks.
  • Implement idempotency: Webhook events may be delivered multiple times due to network issues or retries. Use the webhook-id header to ensure that your system processes the same event only once. Store and check this unique ID before processing.
  • Use constant-time string comparison: When verifying signatures, always use a constant-time string comparison function (e.g., hmac.compare_digest in Python) to mitigate timing attacks.
  • Acknowledge event receipt quickly: Respond to webhook events with a 2xx HTTP status code (e.g., 200 OK, 202 Accepted) as quickly as possible. This confirms successful receipt to our system and prevents unnecessary retries.
  • Process asynchronously: Avoid performing long-running tasks (e.g., complex database writes, sending emails, calling external APIs) directly within your webhook handler. Instead, quickly acknowledge the webhook, then push the event details to a background job queue for asynchronous processing. This prevents timeouts and allows our system to continue delivering other webhooks efficiently.
  • Treat API v2 as the source of truth: While webhooks are highly reliable, no system can guarantee 100% delivery. Use webhooks for near-real-time updates, but occasionally reconcile with API v2 (for example, poll once a week) to ensure your data is fully consistent with the platform state.