Skip to main content

Licenses

Licenses are the core resource in Licentric. Each license is bound to a product and governed by a policy that defines its constraints.

Create License

POST/licenses

Create a new license key. Requires API Key auth with licenses:write scope.

Request Body

ParameterTypeRequiredDescription
productIduuidRequiredID of the product this license belongs to
policyIduuidRequiredID of the policy governing this license
namestringOptionalDisplay name for the license (max 255 chars)
expiresAtdatetimeOptionalExpiration date in ISO 8601 format
maxMachinesOverrideinteger | nullOptionalOverride the policy machine limit for this license
maxUsesOverrideinteger | nullOptionalOverride the policy usage limit for this license
userEmailemailOptionalEmail address of the license holder
userNamestringOptionalName of the license holder (max 255 chars)
entitlementIdsuuid[]OptionalArray of entitlement IDs to attach to this license
metadataobjectOptionalArbitrary key-value metadata
Request
{
  "productId": "d9e5f0a1-4c82-5e6f-a023-9b7c4d8e5f60",
  "policyId": "e0f1a2b3-5d93-6f70-b134-ac8d5e9f6071",
  "name": "Enterprise License",
  "userEmail": "jane@example.com",
  "userName": "Jane Doe",
  "expiresAt": "2027-01-15T00:00:00.000Z",
  "entitlementIds": ["a1b2c3d4-1111-2222-3333-444455556666"],
  "metadata": { "company": "Acme Corp" }
}
201License created
json
{
  "data": {
    "id": "c8f4e9a2-3b71-4d5e-9f12-8a6b3c7d4e5f",
    "key": "DSK-A1B2-C3D4-E5F6-G7H8",
    "name": "Enterprise License",
    "status": "active",
    "productId": "d9e5f0a1-4c82-5e6f-a023-9b7c4d8e5f60",
    "policyId": "e0f1a2b3-5d93-6f70-b134-ac8d5e9f6071",
    "userEmail": "jane@example.com",
    "userName": "Jane Doe",
    "expiresAt": "2027-01-15T00:00:00.000Z",
    "maxMachinesOverride": null,
    "maxUsesOverride": null,
    "usesCount": 12,
    "machineCount": 1,
    "entitlements": ["feature_export", "feature_analytics"],
    "createdAt": "2026-01-15T10:30:00.000Z",
    "updatedAt": "2026-01-15T10:30:00.000Z",
    "deletedAt": null,
    "metadata": {}
  }
}

List Licenses

GET/licenses

List licenses with cursor-based pagination and optional filters. Requires API Key auth with licenses:read scope.

Query Parameters

ParameterTypeRequiredDescription
statusstringOptionalFilter by status: active, expired, suspended, revoked
productIduuidOptionalFilter by product ID
cursoruuidOptionalPagination cursor from previous response
limitintegerOptionalResults per page (1-100, default 25)
Request
GET /api/v1/licenses?status=active&productId=d9e5f0a1-4c82-5e6f-a023-9b7c4d8e5f60&limit=10
200Paginated list
json
{
  "data": [{
    "id": "c8f4e9a2-3b71-4d5e-9f12-8a6b3c7d4e5f",
    "key": "DSK-A1B2-C3D4-E5F6-G7H8",
    "name": "Enterprise License",
    "status": "active",
    "productId": "d9e5f0a1-4c82-5e6f-a023-9b7c4d8e5f60",
    "policyId": "e0f1a2b3-5d93-6f70-b134-ac8d5e9f6071",
    "userEmail": "jane@example.com",
    "userName": "Jane Doe",
    "expiresAt": "2027-01-15T00:00:00.000Z",
    "maxMachinesOverride": null,
    "maxUsesOverride": null,
    "usesCount": 12,
    "machineCount": 1,
    "entitlements": ["feature_export", "feature_analytics"],
    "createdAt": "2026-01-15T10:30:00.000Z",
    "updatedAt": "2026-01-15T10:30:00.000Z",
    "deletedAt": null,
    "metadata": {}
  }
  }],
  "pagination": { "nextCursor": "c8f4e9a2-3b71-4d5e-9f12-8a6b3c7d4e5f", "hasMore": true }
}

Get License

GET/licenses/:id

Retrieve a single license by ID. Requires API Key auth with licenses:read scope.

Request
GET /api/v1/licenses/c8f4e9a2-3b71-4d5e-9f12-8a6b3c7d4e5f
200License details
json
{
  "data": {
    "id": "c8f4e9a2-3b71-4d5e-9f12-8a6b3c7d4e5f",
    "key": "DSK-A1B2-C3D4-E5F6-G7H8",
    "name": "Enterprise License",
    "status": "active",
    "productId": "d9e5f0a1-4c82-5e6f-a023-9b7c4d8e5f60",
    "policyId": "e0f1a2b3-5d93-6f70-b134-ac8d5e9f6071",
    "userEmail": "jane@example.com",
    "userName": "Jane Doe",
    "expiresAt": "2027-01-15T00:00:00.000Z",
    "maxMachinesOverride": null,
    "maxUsesOverride": null,
    "usesCount": 12,
    "machineCount": 1,
    "entitlements": ["feature_export", "feature_analytics"],
    "createdAt": "2026-01-15T10:30:00.000Z",
    "updatedAt": "2026-01-15T10:30:00.000Z",
    "deletedAt": null,
    "metadata": {}
  }
}

Update License

PATCH/licenses/:id

Update a license. Only provided fields are changed. Requires API Key auth with licenses:write scope.

Request Body

ParameterTypeRequiredDescription
namestringOptionalUpdated display name (max 255 chars)
expiresAtdatetime | nullOptionalUpdated expiration date, or null to remove
maxMachinesOverrideinteger | nullOptionalUpdated machine limit override
maxUsesOverrideinteger | nullOptionalUpdated usage limit override
userEmailemail | nullOptionalUpdated license holder email
userNamestring | nullOptionalUpdated license holder name
metadataobjectOptionalMerged with existing metadata
Request
{
  "name": "Enterprise License v2",
  "expiresAt": "2027-06-30T23:59:59.000Z",
  "metadata": { "company": "Acme Corp", "plan": "enterprise" }
}
200Updated license
json
{
  "data": {
    "id": "c8f4e9a2-3b71-4d5e-9f12-8a6b3c7d4e5f",
    "key": "DSK-A1B2-C3D4-E5F6-G7H8",
    "name": "Enterprise License",
    "status": "active",
    "productId": "d9e5f0a1-4c82-5e6f-a023-9b7c4d8e5f60",
    "policyId": "e0f1a2b3-5d93-6f70-b134-ac8d5e9f6071",
    "userEmail": "jane@example.com",
    "userName": "Jane Doe",
    "expiresAt": "2027-01-15T00:00:00.000Z",
    "maxMachinesOverride": null,
    "maxUsesOverride": null,
    "usesCount": 12,
    "machineCount": 1,
    "entitlements": ["feature_export", "feature_analytics"],
    "createdAt": "2026-01-15T10:30:00.000Z",
    "updatedAt": "2026-01-15T10:30:00.000Z",
    "deletedAt": null,
    "metadata": {}
  }
}

Delete License

DELETE/licenses/:id

Soft-delete a license. Sets the deletedAt timestamp. Requires API Key auth with licenses:write scope.

Request
DELETE /api/v1/licenses/c8f4e9a2-3b71-4d5e-9f12-8a6b3c7d4e5f
200Deleted
json
{ "data": { "id": "c8f4e9a2-3b71-4d5e-9f12-8a6b3c7d4e5f", "deleted": true } }

Validate by Key

POST/licenses/validate-key

Validate a license using its raw key. No authentication required -- the key is provided in the request body.

Request Body

ParameterTypeRequiredDescription
keystringRequiredThe full license key (e.g. DSK-A1B2-C3D4-E5F6-G7H8)
fingerprintstringOptionalMachine fingerprint to validate against
entitlementsstring[]OptionalEntitlement codes to check for
Request
{
  "key": "DSK-A1B2-C3D4-E5F6-G7H8",
  "fingerprint": "hw-a1b2c3d4e5f6",
  "entitlements": ["feature_export"]
}
200Validation result
json
{
  "data": {
    "valid": true,
    "code": "VALID",
    "license": {
      "id": "c8f4e9a2-3b71-4d5e-9f12-8a6b3c7d4e5f",
      "name": "Enterprise License",
      "status": "active",
      "expiresAt": "2027-01-15T00:00:00.000Z"
    },
    "machine": {
      "id": "f1a2b3c4-6e04-7081-c245-bd9e6f0a1b82",
      "fingerprint": "hw-a1b2c3d4e5f6",
      "name": "Dev Laptop"
    },
    "entitlements": ["feature_export", "feature_analytics"],
    "metadata": {}
  }
}

Validation Codes

CodeDescription
VALIDLicense is valid and active
EXPIREDLicense has passed its expiration date
SUSPENDEDLicense has been suspended
REVOKEDLicense has been permanently revoked
BANNEDLicense has been banned
NOT_FOUNDNo license exists with the provided key
FINGERPRINT_NOT_FOUNDMachine fingerprint not activated
MACHINE_LIMIT_EXCEEDEDMaximum machine activations reached
HEARTBEAT_REQUIREDMachine heartbeat is required but expired
USES_EXCEEDEDMaximum validation count exceeded
ENTITLEMENTS_MISSINGRequired entitlements not attached

Validate by ID

POST/licenses/:id/validate

Validate a license by its ID. Requires API Key auth with licenses:read scope.

Request Body

ParameterTypeRequiredDescription
fingerprintstringOptionalMachine fingerprint to validate against
entitlementsstring[]OptionalEntitlement codes to check for
200Validation result
json
{
  "data": {
    "valid": true,
    "code": "VALID",
    "license": {
      "id": "c8f4e9a2-3b71-4d5e-9f12-8a6b3c7d4e5f",
      "name": "Enterprise License",
      "status": "active",
      "expiresAt": "2027-01-15T00:00:00.000Z"
    },
    "machine": {
      "id": "f1a2b3c4-6e04-7081-c245-bd9e6f0a1b82",
      "fingerprint": "hw-a1b2c3d4e5f6",
      "name": "Dev Laptop"
    },
    "entitlements": ["feature_export", "feature_analytics"],
    "metadata": {}
  }
}

Suspend License

POST/licenses/:id/suspend

Suspend an active license. Requires API Key auth with licenses:write scope.

Request
POST /api/v1/licenses/c8f4e9a2-3b71-4d5e-9f12-8a6b3c7d4e5f/suspend
200Suspended
json
{
  "data": {
    "id": "c8f4e9a2-3b71-4d5e-9f12-8a6b3c7d4e5f",
    "status": "suspended",
    "updatedAt": "2026-03-01T14:00:00.000Z"
  }
}

Reinstate License

POST/licenses/:id/reinstate

Reinstate a suspended or expired license. Requires API Key auth with licenses:write scope.

Request
POST /api/v1/licenses/c8f4e9a2-3b71-4d5e-9f12-8a6b3c7d4e5f/reinstate
200Reinstated
json
{
  "data": {
    "id": "c8f4e9a2-3b71-4d5e-9f12-8a6b3c7d4e5f",
    "status": "active",
    "updatedAt": "2026-03-01T14:05:00.000Z"
  }
}

Renew License

POST/licenses/:id/renew

Set a new expiration date for a license. Requires API Key auth with licenses:write scope.

Request Body

ParameterTypeRequiredDescription
expiresAtdatetimeRequiredNew expiration date in ISO 8601 format
Request
{ "expiresAt": "2027-12-31T23:59:59.000Z" }
200Renewed
json
{
  "data": {
    "id": "c8f4e9a2-3b71-4d5e-9f12-8a6b3c7d4e5f",
    "status": "active",
    "expiresAt": "2027-12-31T23:59:59.000Z",
    "updatedAt": "2026-03-01T14:10:00.000Z"
  }
}

Offline Checkout

POST/licenses/:id/checkout

Generate a signed offline license certificate. Requires API Key auth with licenses:read scope.

Request Body

ParameterTypeRequiredDescription
fingerprintstringRequiredMachine fingerprint (8-256 characters)
ttlintegerOptionalTime-to-live in seconds (3600-7776000, default 1209600 = 14 days)
Request
{
  "fingerprint": "hw-a1b2c3d4e5f6",
  "ttl": 1209600
}
200Signed certificate
json
{
  "data": {
    "certificate": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9...",
    "ttl": 1209600,
    "expiresAt": "2026-01-29T10:30:00.000Z",
    "fingerprint": "hw-a1b2c3d4e5f6"
  }
}
State Transitions
Valid transitions: active to suspended, active to revoked, suspended to active, suspended to revoked, expired to active. Revoked and banned are terminal states.