A webhook is an automatic HTTP request, usually a POST with a JSON body, that one system sends to a URL you have registered whenever a specific event happens. It reverses the usual API pattern: instead of your system asking again and again "anything new?", the source system tells you the moment something changes. It is sometimes called an HTTP callback.
The URL that receives the request is the webhook endpoint: a route on your server, or in an automation tool, that accepts the delivery, checks that it is genuine and acts on it, for example by opening a ticket or updating a record.
How a webhook works
- Register an endpoint. You give the sending system an HTTPS URL and choose which events it should send. It usually gives you a secret for checking signatures.
- An event happens, such as an alert firing or an order being paid.
- The sender builds a payload, a JSON document describing the event, and signs it with the secret.
- The sender POSTs the payload to your endpoint.
- Your endpoint verifies the signature, replies quickly with a 2xx status code, and queues the real work.
- If it gets no 2xx reply, the sender retries later with increasing gaps between attempts, up to a set limit.
Webhook vs API polling
| Item | Webhook (push) | API polling (pull) |
|---|---|---|
| Who starts it | The sender, when the event happens | Your system, on a schedule |
| Delay | Usually seconds | Up to the polling interval |
| Wasted requests | None; only sent when something happens | Many empty responses |
| If your side is down | Events can be missed once retries run out | You catch up on the next poll |
| Best for | Alerts, notifications, triggering workflows | Bulk sync, reports, catch-up |
Most integrations use both: webhooks for speed, and a periodic API call to reconcile anything missed.
Example webhook payload
This is the shape of a zone-exit alert delivery from Asetavo, shortened from the developer documentation. The values are illustrative.
How to verify a webhook signature (HMAC)
Anyone who learns your endpoint URL can send it requests, so check every signature. Most providers use an HMAC (hash-based message authentication code): the sender computes HMAC-SHA256 of the body with a shared secret and puts it in a header. Your endpoint repeats the calculation:
- Read the raw body as bytes, before any JSON parsing. Re-serialized JSON can differ by a single space and will not match.
- Compute HMAC-SHA256 of the raw body with your stored secret.
- Compare in constant time with the header, for example crypto.timingSafeEqual in Node.js or hmac.compare_digest in Python.
- Reject mismatches with 401 and discard the payload.
- Check the timestamp if the provider signs one, and reject old deliveries to block replays.
- Only then parse and act on the event.
Retries and idempotency
Most webhook systems deliver at least once: if your endpoint times out, the sender cannot tell whether you processed the event, so it sends it again. Your handler must be idempotent, meaning the same event handled twice has the same effect as once. Store each event ID and skip repeats. Reply within a few seconds and queue slow work. Do not assume events arrive in order.
Common uses in asset management
- Open a service desk ticket when a laptop leaves the IT store without a check-out.
- Notify the security team’s channel when equipment leaves a secure cage.
- Update a location field in an ERP when an asset crosses a site boundary.
Common mistakes
- Skipping signature checks, so anyone can post fake events.
- Parsing before verifying, which changes the bytes and breaks the check.
- Doing all the work before replying, which causes timeouts and repeats.
- No deduplication, so a retry opens a second ticket.
Webhooks in Asetavo
In Asetavo, a webhook is a delivery channel on alert rules (Business plan). When a rule fires on left zone, entered zone, an unregistered tag or an exit without a check-out, Asetavo POSTs a signed JSON payload to your HTTPS endpoint. Each rule has its own secret, shown once when you create it, and each delivery carries X-Asetavo-Signature, the hex HMAC-SHA256 of the raw body. Destinations must be public HTTPS hosts: private and loopback addresses are refused and redirects are not followed. Failed deliveries are retried up to 3 times with exponential backoff, so deduplicate on alert_id. More event types are on the roadmap. See API and integrations and the developer docs.
