Skip to content

Webhook best practices

How to build a receiver that stays correct and healthy in production.

Your endpoint must return 2xx well within the 10-second delivery timeout. The reliable pattern:

  1. Validate the request minimally (parse JSON, check X-UCS-Event).
  2. Persist the event to a queue or table.
  3. Return 200 OK.
  4. Process asynchronously from the queue.
flowchart LR
    UCS["Unexus"] -- "POST event" --> EP["Your endpoint"]
    EP -- "1: persist" --> Q[("Queue / table")]
    EP -- "2: 200 OK (fast)" --> UCS
    Q -- "3: process async" --> W["Worker<br/>(CRM lookups, DB writes, APIs)"]

Doing CRM lookups, database writes, or downstream API calls inline is the most common cause of webhook timeouts.

Unexus does not retry failed deliveries. Consequences for your design:

  • Treat webhooks as a real-time signal, not as the system of record.
  • If completeness matters (e.g. reporting), periodically reconcile current state via the REST API (agent state, call state).
  • Monitor your endpoint’s availability — while it is down, events are missed, not queued.

Use the deliveryId (also in the X-UCS-Delivery header) as an idempotency key and skip events you have already processed. This protects you against your own internal retries and makes reprocessing safe.

Events can arrive out of order. Compare occurredAt against the timestamp of the state you already hold, and ignore events older than your current state — a common technique is “last-write-wins by occurredAt per uri”.

  • Ignore unknown JSON fields.
  • Don’t fail on new event types appearing on a shared endpoint; log and skip unknown values of X-UCS-Event.
  • Use HTTPS with a valid certificate — subscription URLs should always be https:// in production.
  • Keep the URL secret and unguessable (e.g. include a random path segment: /hooks/unexus/f3b1c9…). Anyone who knows the URL can send you fake events.
  • Validate the source where possible: restrict by source IP range of your Unexus installation (ask your Unexus contact).
  • Never trust webhook data for authorization decisions — treat payloads as notifications and re-query authoritative state through the authenticated REST API when performing sensitive actions.
  • Deliveries currently carry no signature header. If your security policy requires verifying payload authenticity, raise this with your Unexus contact.
  • Endpoint answers 200 in under a second (queue internally).
  • Idempotency on deliveryId.
  • Out-of-order handling based on occurredAt.
  • Alerting on endpoint downtime and on error responses in your logs.
  • Reconciliation job for data you cannot afford to miss.
  • Separate subscriptions (and URLs) per environment.
  • Test end-to-end with a capture tool (e.g. webhook.site) before go-live.