Webhook Best Practices
Follow these practices to build a reliable and secure webhook handler.
Use the raw request body
Always verify the signature against the raw bytes — never re-serialize parsed JSON. JSON serialization is not deterministic and will produce a different signature. In Express, use express.raw() before any JSON parsing middleware.
Use timing-safe comparison
Never use plain string equality to compare signatures — it leaks timing information. Use timingSafeEqual (Node.js), hmac.compare_digest (Python), hash_equals (PHP), or hmac.Equal (Go).
Make handlers idempotent
Artos delivers webhooks with at-least-once semantics. Your handler may receive the same event more than once after a manual retry. Use data.transactionId to deduplicate events in your database before processing.
Respond quickly
Your endpoint must respond with a 2xx status within 10 seconds. Return 200 OK immediately and process the event asynchronously via a job queue if your logic takes longer.
Use HTTPS
Always use an HTTPS URL for your webhook endpoint. HTTP endpoints are not supported in production.