Skip to main content

Policy Fields Reference

Canonical reference for every policy field — API name, type, validation rule, DB column, and default. These names are part of the Licentric v1 stability contract: any rename will follow a deprecation cycle of at least one minor version.

Why this reference matters
SDK consumers hardcode these field names. Once a name ships in a published SDK release, renaming it is a breaking change. The names below are frozen for v1 — extensions ship as new fields, not renames.

All Fields

API NameTypeValidationDB ColumnDefault
idstring (UUID)auto-generatedidgen_random_uuid()
productIdstring (UUID).uuid()product_id
namestring.min(1).max(255)name
templateenum | null"desktop_app" | "cli_tool" | "saas" | "trial" | "custom"templatenull
maxMachinesinteger | null.int().positive()max_machinesnull
maxUsesinteger | null.int().positive()max_usesnull
floatingboolean.boolean()floatingfalse
durationDaysinteger | null.int().positive()duration_daysnull
expirationStrategyenum"RESTRICT_ACCESS" | "ALLOW_ACCESS" | "REVOKE"expiration_strategy"RESTRICT_ACCESS"
requireHeartbeatboolean.boolean()require_heartbeatfalse
heartbeatIntervalMinutesinteger.int().min(1)heartbeat_interval_minutes60
heartbeatCullStrategyenum"DEACTIVATE_DEAD" | "KEEP_DEAD"heartbeat_cull_strategy"DEACTIVATE_DEAD"
requireFingerprintboolean.boolean()require_fingerprinttrue
fingerprintUniquenessenum"PER_LICENSE" | "PER_POLICY" | "PER_ACCOUNT"fingerprint_uniqueness"PER_LICENSE"
offlineAllowedboolean.boolean()offline_allowedtrue
offlineMaxDaysinteger.int().min(1)offline_max_days14
allowMachineTransferboolean.boolean()allow_machine_transferfalse
isTrialboolean.boolean()is_trialfalse
trialDurationDaysinteger | null.int().positive()trial_duration_daysnull
overridableboolean.boolean()overridabletrue
maxUniqueFingerprintsinteger | null.int().positive()max_unique_fingerprintsnull
metadataobject.record(z.string(), z.unknown())metadata{}

Field Descriptions

id

Unique identifier for the policy.

productId

The product this policy is bound to. All licenses created against this policy belong to this product.

name

Human-readable label for the policy (shown in dashboard).

template

Optional template that pre-fills sensible defaults. The template is recorded but does not constrain other field values.

maxMachines

Maximum machines that can be activated against a license under this policy. null = unlimited. Per-license override available via maxMachinesOverride.

maxUses

Maximum validate-key calls allowed before the license is exhausted. null = unlimited. Per-license override available via maxUsesOverride.

floating

When true, activating a new machine after the limit auto-deactivates the oldest machine instead of rejecting. Useful for floating-seat licensing.

durationDays

Default expiration window for new licenses created under this policy (computed from createdAt). null = perpetual. Overridden by explicit expiresAt on createLicense.

expirationStrategy

Behavior when a license expires. RESTRICT_ACCESS: validation fails. ALLOW_ACCESS: validation succeeds with code=EXPIRED_ALLOWED (use sparingly — eliminates renewal pressure). REVOKE: status flips to revoked at expiry.

requireHeartbeat

When true, machines must send periodic heartbeats or are considered dead.

heartbeatIntervalMinutes

How often a machine must heartbeat. Validation marks a machine dead if 2× this interval has elapsed since the last heartbeat.

heartbeatCullStrategy

Action taken when a machine is detected as dead. DEACTIVATE_DEAD: free the activation slot. KEEP_DEAD: keep the slot occupied (machine count unchanged).

requireFingerprint

When true, every activation/validation must include a machine fingerprint. Disable only for SaaS-style licensing where the customer is the unit, not the device.

fingerprintUniqueness

Scope at which a fingerprint must be unique. PER_LICENSE allows the same machine on multiple licenses; PER_POLICY blocks reuse across licenses sharing this policy; PER_ACCOUNT blocks reuse anywhere in the account.

offlineAllowed

When true, the SDK can issue offline license files (signed certificates) via /licenses/{id}/checkout. Disable for environments where offline use is forbidden.

offlineMaxDays

Maximum TTL (in days) the SDK can request when checking out an offline license file. Hard ceiling — requests beyond this are rejected.

allowMachineTransfer

When true, customers can deactivate one machine and re-activate on a new one without admin intervention. Disable to require manual support for transfers.

isTrial

Marker that licenses created under this policy are trials. Used for analytics and conversion tracking; does not by itself enforce expiration.

trialDurationDays

Default trial length when isTrial=true. Functions as durationDays for trial licenses.

overridable

When false, per-license overrides (maxMachinesOverride, maxUsesOverride) are rejected at creation. Enforces strict policy compliance.

maxUniqueFingerprints

Sharing-detection threshold. When more than this many distinct fingerprints validate the same license, a license.sharing_detected event fires. null = detection disabled.

metadata

Free-form JSON for integrator-specific data. Common uses: feature flags, tier labels, pricing-plan back-references, A/B test markers.

Naming Conventions

  • API field names use camelCase (maxMachines).
  • DB columns use snake_case (max_machines).
  • Repository layer maps automatically — application code only ever touches the camelCase form.
  • Boolean fields prefixed with allow, require, is, or no prefix when neutral.
  • Duration fields suffixed with their unit: Days, Minutes.

Alternative Names (Not Currently Exposed)

Some external sources or community discussions reference policy concepts with different names than the Licentric v1 contract. Those alternative names are not currently exposed in the API. If you see these in third-party tutorials, translate to the canonical names above:

AlternativeCanonical (use this)Notes
maxActivationsmaxMachines + maxUsesLicentric splits machine count from validation count — they enforce different limits.
transferAllowedallowMachineTransferLicentric prefixes permission booleans with allow.
trialDaystrialDurationDaysLicentric uses an explicit Duration infix for time spans.
bindingStrategyfingerprintUniquenessDifferent semantics — bindingStrategy implies which identifier; fingerprintUniqueness only controls scope.
revalidationIntervalMinutesheartbeatIntervalMinutesLicentric ties revalidation to the heartbeat protocol.
gracePeriodDays(on stripe_mappings, not policies)Per-Stripe-mapping field — payment-failure grace, not policy-level.
transferCooldownDays(not currently exposed)No equivalent. Tracked for a future minor release.
featureFlagsmetadata.featureFlagsStored inside the free-form metadata JSON field by convention.
Stability guarantee
The canonical names in the first table will not change for v1 of the Licentric API. New fields may be added; existing fields will not be renamed without a deprecation cycle of at least one minor version.