Guides
Issue licenses, set their terms with policies, and suspend, renew, or revoke them as your customers' situations change.
| Type | Expires | Use it for |
|---|---|---|
| Perpetual | Never | One-time purchases. |
| Timed | Yes | Annual or fixed-term licenses. |
| Trial | Yes | Free evaluations. |
| Subscription | Yes | Recurring plans. Renew the license each time a payment succeeds. |
Keys look like ATLAS-7K2M-9QXD-…. Set your own prefix (up to 12 letters or numbers) on each product, or remove it entirely. The prefix is cosmetic: changing it never breaks keys you've already issued, and customers can type a key with or without it.
A policy holds the terms you sell over and over:
| Setting | What it does |
|---|---|
| License type and duration | How long a new license lasts, in days. |
| Device limit | How many devices can be active at once (1–1,000). |
| Grace period | Days a license keeps working after it expires, so a late renewal doesn't lock anyone out. |
| Offline access | Whether devices can work offline, and for how long. |
| Default entitlements | The features and limits new licenses start with. |
Terms are copied onto each license when it's issued. Editing a policy later only affects new licenses, so existing customers keep exactly what they bought. Archive a policy to stop offering it.
Entitlements are the features and limits your app reads after a successful check. Values can be true/false, numbers, or text.
{ "plan": "pro", "seats": 5, "export.pdf": true, "support": "priority" }Keys use lowercase letters, numbers, ., _, and -, with up to 100 per license. Change them at any time (for example on an upgrade) and the app sees the new values on its next check.
Attach a customer when you issue a license: pick an existing one, or pass an email and your own ID (for example your billing system's customer ID). Issuing another license with the same ID reuses that customer. The Customers page shows each customer's licenses in one place, which makes support requests quick.
| Action | Effect | Undo |
|---|---|---|
| Suspend | Blocks the license temporarily, for example during a payment dispute. | Reinstate |
| Renew | Sets a new expiry date. Use it for every subscription payment. | — |
| Edit | Changes entitlements, metadata, or the device limit. | Edit again |
| Revoke | Blocks the license permanently. You'll pick a reason, such as a refund or chargeback. | Not possible |
Changes reach your app on its next online check. Every change is recorded in the license's history and in your organization's audit log.
| Status | Meaning |
|---|---|
| Active | Usable, as long as it has started and hasn't passed its expiry plus grace period. |
| Suspended | Temporarily blocked. |
| Revoked | Permanently blocked. |
| Expired | Past its expiry date and grace period. Renew it to restore access. |
| Superseded | Replaced by a newer license. |
To issue licenses from your own checkout, call the API with a secret key. Pass an idempotency key such as your order ID, so a retried request never creates a second license.
import { AtlasClient } from "@atlas/sdk";
const atlas = new AtlasClient({ apiKey: process.env.ATLAS_SECRET_KEY! });
const issued = await atlas.licenses.create(
{
product_id: "prod_...",
policy_id: "pol_...",
customer: { external_id: order.customerId, email: order.email },
},
{ idempotencyKey: `order-${order.id}` },
);
sendEmail(order.email, issued.key); // the full key is only returned here