How to use webhooks
A webhook pushes events from UniAsset to a URL you control, so your systems find out when something happens without polling.
Requirements
- Available on: Odyssey, Cosmos
- Roles: Owner only
- An HTTPS endpoint you control. Plain HTTP is rejected.
Steps
- Go to Settings → Integrations → Webhooks.
- Click New Webhook.
- Enter:
| Setting | Notes |
|---|---|
| Name | What this webhook is for |
| URL | Your HTTPS endpoint |
| Events | Which events to subscribe to |
- Save. A signing secret is generated — store it securely.
The thirteen events
| Event | Fires when |
|---|---|
asset.created | An asset is created |
asset.updated | An asset record is updated |
asset.assigned | An asset assignment changes |
geo_position.updated | Geo-position data is updated |
maintenance.created | A service record is created |
maintenance.due_soon | Maintenance approaches its due date |
maintenance.overdue | Maintenance passes its due date |
document.expiring | An attached document nears expiry |
document.expired | An attached document has expired |
document_asset.expiring | A document asset nears expiry |
document_asset.expired | A document asset has expired |
warranty.expiring | An asset warranty nears expiry |
incident.created | An incident is recorded |
Subscribe only to what you will act on.
What a delivery looks like
Each delivery is a POST carrying the event name, a timestamp, and a signature in the headers, with a JSON body containing the event and its data.
Verify the signature
Always verify. Compute an HMAC-SHA256 of the raw request body using your signing secret, and compare it to the signature header using a constant-time comparison.
Important Verify against the raw body, before any JSON parsing or re-serialisation. Re-encoding changes the bytes and the digest will not match.
Full worked examples in several languages: Verifying webhook signatures.
Delivery and retries
Deliveries are queued, never sent inline, so a slow endpoint on your side never slows UniAsset down. A job processes the queue every minute.
Any non-2xx response or transport error is retried:
| Attempt | Delay after the previous one |
|---|---|
| 2 | 30 seconds |
| 3 | 2 minutes |
| 4 | 10 minutes |
| 5 | 1 hour |
After five attempts the delivery is marked failed and the last error recorded. You can see every delivery with its status, attempt count, and error.
Make your handler idempotent
A retry can arrive after your endpoint already processed the first attempt but failed to respond in time. If your handler is not idempotent, that duplicate does damage.
Return 2xx quickly and do the work asynchronously. A handler that does slow work before responding will time out and be retried, which makes the problem worse.
What happens if you downgrade
Webhooks are not deactivated by a plan change. Deliveries for organizations without the webhook capability are simply dropped without an HTTP call, and resume on upgrade with nothing to reconfigure.
Common mistakes
Not verifying the signature. Without it, anyone who learns your URL can post to it.
Verifying against parsed JSON. The digest is over the raw bytes.
Doing heavy work before responding. You will time out and be retried.
Assuming exactly-once delivery. Design for redelivery.
Subscribing to every event. Volume you ignore is volume you still have to process.
Troubleshooting
Webhooks isn't in my Settings. It needs Odyssey or above, and Owner.
My HTTP URL was rejected. Webhook targets must be HTTPS.
Signature verification always fails. You are almost certainly verifying against a re-serialised body rather than the raw one.
Deliveries show as failed. Check the recorded error. Common causes are timeouts, non-2xx responses, and TLS problems on your endpoint.
Deliveries stopped entirely. Check your plan still includes webhooks. Deliveries are dropped for organizations without the capability.
I'm getting the same event twice. That is a retry. Make the handler idempotent.
Related articles
Need Help?
If you have questions not covered in this article, our support team is here to help.
Contact Support