Skip to main content

Policies

Policies define the rules and constraints for licenses. Each license is governed by exactly one policy, which determines machine limits, expiration behavior, heartbeat requirements, offline support, and more.

Create Policy

POST/policies

Create a new licensing policy. Requires API Key auth with policies:write scope.

Request Body

ParameterTypeRequiredDescription
productIduuidRequiredID of the product this policy belongs to
namestringRequiredPolicy name (1-255 characters)
templateenumOptionalPolicy template: desktop_app, cli_tool, saas, trial, or custom
maxMachinesinteger | nullRequiredMaximum machine activations per license. Required: a positive integer pins the limit; null requires paired allowUnlimitedActivations:true (explicit-consent gate, integrator 360° audit Issue 1 — prevents silent unbounded-seat policies).
allowUnlimitedActivationsbooleanOptionalPair with maxMachines:null to opt the policy into unlimited per-license activations. Request-time guardrail; not persisted (stripped at the route boundary). Default: false.
maxUsesinteger | nullOptionalMaximum validation count per license (null = unlimited)
floatingbooleanOptionalEnable floating licenses (default: false)
durationDaysinteger | nullOptionalAuto-expiration in days from license creation (null = no auto-expiry)
expirationStrategyenumOptionalBehavior on expiry: RESTRICT_ACCESS (default), ALLOW_ACCESS, or REVOKE
requireHeartbeatbooleanOptionalRequire periodic machine heartbeats (default: false)
heartbeatIntervalMinutesintegerOptionalHeartbeat interval in minutes (default: 60, min: 1)
heartbeatCullStrategyenumOptionalDead machine handling: DEACTIVATE_DEAD (default) or KEEP_DEAD
requireFingerprintbooleanOptionalRequire machine fingerprint on validation (default: true)
fingerprintUniquenessenumOptionalFingerprint scope: PER_LICENSE (default), PER_POLICY, or PER_ACCOUNT
offlineAllowedbooleanOptionalAllow offline license checkout (default: true)
offlineMaxDaysintegerOptionalMax days a license can operate offline (default: 14, min: 1)
allowMachineTransferbooleanOptionalAllow deactivating and reactivating on a different machine (default: false)
isTrialbooleanOptionalMark this as a trial policy (default: false)
trialDurationDaysinteger | nullOptionalTrial duration in days (null = use durationDays)
overridablebooleanOptionalAllow per-license overrides of maxMachines and maxUses (default: true)
entitlementIdsuuid[]OptionalEntitlements automatically granted to licenses using this policy
metadataobjectOptionalArbitrary key-value metadata
Request
{
  "productId": "d9e5f0a1-4c82-5e6f-a023-9b7c4d8e5f60",
  "name": "Standard Desktop License",
  "template": "desktop_app",
  "maxMachines": 3,
  "durationDays": 365,
  "requireFingerprint": true,
  "offlineAllowed": true,
  "offlineMaxDays": 14,
  "entitlementIds": ["a1b2c3d4-1111-2222-3333-444455556666"],
  "metadata": {}
}
201Policy created
json
{
  "data": {
    "id": "e0f1a2b3-5d93-6f70-b134-ac8d5e9f6071",
    "productId": "d9e5f0a1-4c82-5e6f-a023-9b7c4d8e5f60",
    "name": "Standard Desktop License",
    "template": "desktop_app",
    "maxMachines": 3,
    "maxUses": null,
    "floating": false,
    "durationDays": 365,
    "expirationStrategy": "RESTRICT_ACCESS",
    "requireHeartbeat": false,
    "heartbeatIntervalMinutes": 60,
    "heartbeatCullStrategy": "DEACTIVATE_DEAD",
    "requireFingerprint": true,
    "fingerprintUniqueness": "PER_LICENSE",
    "offlineAllowed": true,
    "offlineMaxDays": 14,
    "allowMachineTransfer": false,
    "isTrial": false,
    "trialDurationDays": null,
    "overridable": true,
    "entitlementIds": ["a1b2c3d4-1111-2222-3333-444455556666"],
    "createdAt": "2026-01-12T09:00:00.000Z",
    "updatedAt": "2026-01-12T09:00:00.000Z",
    "deletedAt": null,
    "metadata": {}
  }
}

List Policies

GET/policies

List all policies with cursor-based pagination. Requires API Key auth with policies:read scope.

Query Parameters

ParameterTypeRequiredDescription
cursoruuidOptionalPagination cursor from previous response
limitintegerOptionalResults per page (1-100, default 25)
Request
GET /api/v1/policies?limit=25
200Paginated list
json
{
  "data": [
    {
      "id": "e0f1a2b3-5d93-6f70-b134-ac8d5e9f6071",
      "productId": "d9e5f0a1-4c82-5e6f-a023-9b7c4d8e5f60",
      "name": "Standard Desktop License",
      "template": "desktop_app",
      "maxMachines": 3,
      "maxUses": null,
      "floating": false,
      "durationDays": 365,
      "expirationStrategy": "RESTRICT_ACCESS",
      "requireHeartbeat": false,
      "requireFingerprint": true,
      "offlineAllowed": true,
      "overridable": true,
      "createdAt": "2026-01-12T09:00:00.000Z",
      "updatedAt": "2026-01-12T09:00:00.000Z",
      "deletedAt": null,
      "metadata": {}
    }
  ],
  "pagination": {
    "nextCursor": null,
    "hasMore": false
  }
}

Policy Templates

Templates provide sensible defaults for common licensing models. You can override any field when creating a policy.

TemplateUse CaseKey Defaults
desktop_appNative desktop applicationsFingerprint required, offline allowed, 3 machines
cli_toolCommand-line tools and utilitiesFingerprint required, no machine limit
saasWeb-based SaaS applicationsNo fingerprint, no machine limit, heartbeat optional
trialTime-limited free trials14-day duration, 1 machine, not overridable
customFully custom configurationNo defaults applied
Overridable Policies
When overridable is true (the default), individual licenses can override maxMachines and maxUses using the per-license override fields.
Explicit consent for unlimited seats
maxMachines requires a positive integer on create. To opt a policy into unlimited per-license activations, send "maxMachines": null AND "allowUnlimitedActivations": true in the same request. The same gate fires on PATCH when widening a finite limit to null. This prevents a typo or omitted field from silently shipping an unbounded-seat license; the flag is request-time only and is never persisted.