AssetTrove Help centre assettrove.eu

Webhooks

Get notified in your own systems when things happen in AssetTrove, and verify that each message is genuine.

Updated 13 November 2026

A webhook sends a message to your system whenever something happens in AssetTrove. For example: open a service desk ticket when a compliance control fails, or update your ERP when a depreciation period closes. You need permission to manage webhooks (Owners and Admins have it).

Add an endpoint

  1. Go to Webhooks and add an endpoint. It must be a public HTTPS address.
  2. Choose the events you want.
  3. Copy the signing secret.
  4. Select Send test to receive a ping.

Events

Event When
asset.created, asset.updated An asset is added or changed
asset.assigned, asset.returned, asset.transferred Custody changes
asset.retired, asset.disposed, asset.lost, asset.found Lifecycle changes
asset.recovery_requested A device needs collecting from someone who left
discovery.run_completed A discovery run finished
device.match_conflict A device needs review
allocation.created, allocation.revoked, allocation.promoted Licence seats change
entitlement.expiring 90, 60, 30 and 7 days before an entitlement ends
contract.renewal_notice A contract's renewal notice deadline is near
reconciliation.completed A licence position run finished
compliance.shortfall_detected A product is short of licences
reclamation.candidate_detected, reclamation.reclaimed, reclamation.failed Reclamation progress
user.provisioned, user.deactivated, user.reactivated People change
depreciation.period_closed A month is closed, with totals per book and cost centre
compliance.control_failed A compliance check failed

Messages contain IDs and a small summary, never secrets. Fetch more detail with the API if you need it.

Verify every message

Each message has an ITAM-Signature header: t=<unix time>,v1=<signature>. The signature is an HMAC-SHA256 of the time, a full stop, and the raw body, using your signing secret. Reject messages older than 5 minutes, and compare signatures in constant time.

import crypto from "node:crypto";

function isGenuine(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(",").map(p => p.split("=")));
  const age = Math.abs(Date.now() / 1000 - Number(parts.t));
  if (!parts.t || age > 300) return false;
  const expected = crypto.createHmac("sha256", secret).update(parts.t + "." + rawBody).digest("hex");
  // During secret rotation the header holds two v1 values; accept either.
  return header.split(",").filter(p => p.startsWith("v1=")).some(p => {
    const got = Buffer.from(p.slice(3), "hex"), want = Buffer.from(expected, "hex");
    return got.length === want.length && crypto.timingSafeEqual(got, want);
  });
}

Delivery and retries

  • Any 2xx response counts as delivered.
  • Failed deliveries are retried after 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours and 24 hours.
  • After 3 days of continuous failure, the endpoint is disabled and admins are emailed.
  • You can see every delivery and redeliver any of them from the endpoint's page.
  • Messages can occasionally arrive more than once. Use the ITAM-Event-Id header to ignore duplicates.

Rotating the secret

Select Rotate secret. The old secret keeps working for 24 hours, and during that time each message carries both signatures, so you can switch over without missing anything.

Still have a question? Email rory@assettrove.eu and we'll get back to you.