API reference

Generated from the same schemas the API validates with. Machine-readable version: /api/v1/openapi.json. All timestamps are ISO 8601 UTC; all ids are prefixed strings.

Public license API

Called by your software on end-user machines.

post/api/v1/licenses/validateValidate a license

Check a key (optionally for a machine fingerprint). Always 200 for well-formed requests; read `data.valid` and `data.code`.

Request body
{
  key: string
  fingerprint?: string
  product_id?: string
  app_version?: string
  nonce?: string
}
Response 200
{
    ok: true
    data: ValidationResult
  }
post/api/v1/licenses/activateActivate a machine

Claims a seat for `fingerprint`. Idempotent per fingerprint. Fails with 422 and a validation code (NO_SEATS, REVOKED, EXPIRED …) when not allowed.

Request body
{
  key: string
  fingerprint: string
  product_id?: string
  name?: string
  platform?: string
  hostname?: string
  app_version?: string
  metadata?: object
  nonce?: string
}
Response 200
{
    ok: true
    data: ValidationResult
  }
post/api/v1/licenses/deactivateDeactivate a machine

Frees the seat held by `fingerprint`.

Request body
{
  key: string
  fingerprint: string
  product_id?: string
  nonce?: string
}
Response 200
{
    ok: true
    data: ValidationResult
  }
post/api/v1/licenses/heartbeatHeartbeat

Extends a floating lease / keeps a node-locked seat alive. Call at least every lease interval.

Request body
{
  key: string
  fingerprint: string
  product_id?: string
  app_version?: string
  nonce?: string
}
Response 200
{
    ok: true
    data: ValidationResult
  }
get/api/v1/licenses/{key}/certificateOffline certificate

Signed license file for offline verification with the product public key. Bind it to a machine with `fingerprint`. Add `format=file` for a downloadable `.lic`.

ParameterInType
key *pathstring
fingerprintquerystring
ttlqueryinteger — Seconds, max 1 year, default 30 days
product_idquerystring
formatqueryjson | file
Response 200
{
    ok: true
    data: object
  }
get/api/v1/products/{id}/public-keyProduct signing keys
ParameterInType
id *pathstring
Response 200
{
    ok: true
    data: object
  }
get/api/v1/public-keyPlatform response-signing key
Response 200
{
    ok: true
    data: object
  }

Management API

Called by your backend with an API key from Developers → API keys.

get/api/v1/licensesList licenses

Cursor-paginated, newest first. Filter by status, product, customer, key or free text.

ParameterInType
statusqueryactive | suspended | revoked | expired
product_idquerystring
policy_idquerystring
customer_idquerystring
keyquerystring
qquerystring
expiring_beforequerystringnull
cursorquerystring
limitqueryinteger
Response 200
{
  ok: true
  data: License[]
}
post/api/v1/licensesCreate a license

Send an `Idempotency-Key` header to make retries safe.

Request body
{
  product_id: string
  policy_id: string
  customer_id?: string,null
  customer?: object,null
  expires_at?: string,null
  max_activations?: integer,null
  entitlements?: object,null
  metadata?: object
  name?: string,null
  notes?: string,null
  send_email?: boolean
}
Response 201
{
  ok: true
  data: License
}
get/api/v1/licenses/{id}Get a license
ParameterInType
id *pathstring
Response 200
{
  ok: true
  data: License
}
patch/api/v1/licenses/{id}Update a license
ParameterInType
id *pathstring
Request body
{
  name?: string,null
  notes?: string,null
  metadata?: object
  entitlements?: object,null
  max_activations?: integer,null
  customer_id?: string,null
  policy_id?: string
  expires_at?: string,null
}
Response 200
{
  ok: true
  data: License
}
delete/api/v1/licenses/{id}Delete a license
ParameterInType
id *pathstring
Response 200
{
  ok: true
  data: object
}
post/api/v1/licenses/{id}/revokeRevoke (removes all activations)
ParameterInType
id *pathstring
Request body
{
  reason?: string,null
}
Response 200
{
  ok: true
  data: License
}
post/api/v1/licenses/{id}/suspendSuspend (validation fails until reinstated)
ParameterInType
id *pathstring
Request body
{
  reason?: string,null
}
Response 200
{
  ok: true
  data: License
}
post/api/v1/licenses/{id}/reinstateReinstate a suspended or revoked license
ParameterInType
id *pathstring
Response 200
{
  ok: true
  data: License
}
post/api/v1/licenses/{id}/renewRenew for one policy period
ParameterInType
id *pathstring
Response 200
{
  ok: true
  data: License
}
post/api/v1/licenses/{id}/extendExtend expiry
ParameterInType
id *pathstring
Request body
{
  days?: integer
  expires_at?: string,null
}
Response 200
{
  ok: true
  data: License
}
get/api/v1/licenses/{id}/activationsList activations
ParameterInType
id *pathstring
include_inactivequerytrue | false
Response 200
{
  ok: true
  data: Activation[]
}
delete/api/v1/licenses/{id}/activations/{activationId}Deactivate a machine
ParameterInType
id *pathstring
activationId *pathstring
Response 200
{
  ok: true
  data: Activation
}
get/api/v1/customersList customers
ParameterInType
qquerystring
emailquerystring
external_idquerystring
cursorquerystring
limitqueryinteger
Response 200
{
  ok: true
  data: any[]
}
post/api/v1/customersCreate a customer

Returns the existing customer when the email already exists.

Request body
{
  email: string
  name?: string,null
  external_id?: string,null
  stripe_customer_id?: string,null
  metadata?: object
}
Response 201
{
  ok: true
  data: Customer
}
get/api/v1/customers/{id}Get a customer
ParameterInType
id *pathstring
Response 200
{
  ok: true
  data: Customer
}
patch/api/v1/customers/{id}Update a customer
ParameterInType
id *pathstring
Request body
{
  email?: string
  name?: string,null
  external_id?: string,null
  stripe_customer_id?: string,null
  metadata?: object
}
Response 200
{
  ok: true
  data: Customer
}
delete/api/v1/customers/{id}Delete a customer
ParameterInType
id *pathstring
Response 200
{
  ok: true
  data: object
}
get/api/v1/productsList products
Response 200
{
  ok: true
  data: any[]
}
post/api/v1/productsCreate a product
Request body
{
  name: string
  slug?: string
  key_prefix: string
  description?: string,null
}
Response 201
{
  ok: true
  data: any
}
get/api/v1/products/{id}Get a product
ParameterInType
id *pathstring
Response 200
{
  ok: true
  data: any
}
patch/api/v1/products/{id}Update a product
ParameterInType
id *pathstring
Request body
{
  name?: string
  slug?: string
  key_prefix?: string
  description?: string,null
}
Response 200
{
  ok: true
  data: Product
}
delete/api/v1/products/{id}Delete a product
ParameterInType
id *pathstring
Response 200
{
  ok: true
  data: object
}
get/api/v1/products/{id}/policiesList a product's policies
ParameterInType
id *pathstring
Response 200
{
  ok: true
  data: Policy[]
}
get/api/v1/policiesList policies
ParameterInType
product_idquerystring
Response 200
{
  ok: true
  data: Policy[]
}
post/api/v1/policiesCreate a policy
Request body
{
  product_id: string
  name: string
  description?: string,null
  duration_days?: integer,null
  duration_start?: "creation" | "first_activation"
  max_activations?: integer,null
  activation_strategy?: "node_locked" | "floating"
  heartbeat_cull_minutes?: integer,null
  lease_duration_minutes?: integer
  require_fingerprint?: boolean
  overage_strategy?: "deny" | "allow"
  max_overage?: integer
  grace_period_days?: integer
  expiry_behaviour?: "invalidate" | "restrict"
  entitlements?: object
  restricted_entitlements?: object
  metadata?: object
  is_default?: boolean
}
Response 201
{
  ok: true
  data: Policy
}
get/api/v1/policies/{id}Get a policy
ParameterInType
id *pathstring
Response 200
{
  ok: true
  data: Policy
}
patch/api/v1/policies/{id}Update a policy
ParameterInType
id *pathstring
Request body
{
  name?: string
  description?: string,null
  duration_days?: integer,null
  duration_start?: "creation" | "first_activation"
  max_activations?: integer,null
  activation_strategy?: "node_locked" | "floating"
  heartbeat_cull_minutes?: integer,null
  lease_duration_minutes?: integer
  require_fingerprint?: boolean
  overage_strategy?: "deny" | "allow"
  max_overage?: integer
  grace_period_days?: integer
  expiry_behaviour?: "invalidate" | "restrict"
  entitlements?: object
  restricted_entitlements?: object
  metadata?: object
  is_default?: boolean
}
Response 200
{
  ok: true
  data: Policy
}
delete/api/v1/policies/{id}Delete a policy
ParameterInType
id *pathstring
Response 200
{
  ok: true
  data: object
}
get/api/v1/webhooksList webhook endpoints
Response 200
{
  ok: true
  data: WebhookEndpoint[]
}
post/api/v1/webhooksCreate a webhook endpoint

Events: license.created, license.updated, license.renewed, license.suspended, license.reinstated, license.revoked, license.expired, license.expiring_soon, activation.created, activation.deleted, activation.lease_expired, customer.created, customer.updated or "*".

Request body
{
  url: string
  description?: string,null
  events: string[]
  enabled?: boolean
}
Response 201
{
  ok: true
  data: any
}
get/api/v1/webhooks/{id}Get a webhook endpoint
ParameterInType
id *pathstring
Response 200
{
  ok: true
  data: WebhookEndpoint
}
patch/api/v1/webhooks/{id}Update a webhook endpoint
ParameterInType
id *pathstring
Request body
{
  url?: string
  description?: string,null
  events?: string[]
  enabled?: boolean
}
Response 200
{
  ok: true
  data: WebhookEndpoint
}
delete/api/v1/webhooks/{id}Delete a webhook endpoint
ParameterInType
id *pathstring
Response 200
{
  ok: true
  data: object
}