Guides
Get notified on your own server when licenses are created, activated, renewed, or revoked.
whsec_…). It's shown only once.| Event | Sent when |
|---|---|
| license.created | A license is issued. |
| license.updated | Entitlements, metadata, or the device limit change. |
| license.activated | A device activates the license. |
| license.deactivated | A device is released. |
| license.renewed | The license gets a new expiry date. |
| license.suspended | The license is suspended. |
| license.reinstated | A suspended license is reinstated. |
| license.revoked | The license is revoked. |
| license.expired | A check finds the license past its expiry and grace period. |
| activation.limit_reached | A device is refused because every slot is in use. |
| customer.created | A new customer is created along with a license. |
| customer.updated | A customer's details change when a license is issued. |
{
"id": "evt_...",
"type": "license.activated",
"created_at": "2026-10-24T09:12:44.000Z",
"environment_id": "env_...",
"data": {
"license": { "id": "lic_...", "status": "active", "entitlements": { "plan": "pro" } },
"activation": { "id": "act_...", "device_id": "install_9f2c", "status": "active" }
}
}Each request has an Atlas-Signature header. Check it before trusting the request, using the raw body exactly as received.
import express from "express";
import { verifyWebhook } from "@atlas/sdk";
app.post("/atlas/webhooks", express.raw({ type: "application/json" }), async (req, res) => {
const result = await verifyWebhook(
req.body.toString("utf8"),
req.headers,
process.env.ATLAS_WEBHOOK_SECRET!,
);
if (!result.valid) return res.status(400).send(result.reason);
if (result.event.type === "license.revoked") {
await disableAccount(result.event.data.license.id);
}
res.sendStatus(200);
});The header looks like t=1761100800,v1=5f2c…. Compute HMAC-SHA256 of `${t}.${rawBody}` with your signing secret, hex-encode it, and compare it to v1 with a constant-time comparison. Reject requests where t is more than five minutes old.
Atlas-Event-Id) to skip duplicates.If a secret leaks or is lost, rotate it from the endpoint page. The new secret applies from the next delivery, so update your server straight away.