Skip to main content

SDKs

Python SDK

Synchronous HTTP client for the Licentric licensing API, powered by httpx and Pydantic.

Requirements
Python 3.8 or higher. Dependencies: httpx and pydantic.

Installation

Install
pip install licentric

# Or install from source
git clone https://github.com/AbleVarghese/licentric.git
cd licentric/sdks/python
pip install -e .

Client Initialization

setup.py
from licentric import Licentric

# Initialize with your API key
client = Licentric(api_key="lk_live_your_api_key_here")

# With custom options
client = Licentric(
    api_key="lk_live_your_api_key_here",
    base_url="https://your-instance.licentric.com",
    timeout=30.0,
)

# Use as a context manager to auto-close connections
with Licentric(api_key="lk_live_...") as client:
    result = client.validate("MYAPP-XXXX-XXXX-XXXX-XXXX")

Constructor Parameters

ParameterTypeRequiredDescription
api_keystrRequiredYour Licentric API key (lk_live_... or lk_test_...)
base_urlstrOptionalAPI base URL. Defaults to https://licentric.com
timeoutfloatOptionalRequest timeout in seconds. Defaults to 30.0

Methods

validate()

Validate a license key. This endpoint authenticates via the license key itself — no API key header is required for validation.

ParameterTypeRequiredDescription
keystrRequiredThe license key to validate
fingerprintstr | NoneOptionalMachine fingerprint to check device activation
entitlementslist[str] | NoneOptionalEntitlement codes the license must satisfy

Returns a ValidationResult with valid, code, license, machine, and entitlements.

validate.py
result = client.validate(
    key="MYAPP-XXXX-XXXX-XXXX-XXXX",
    fingerprint="abc123def456",        # optional
    entitlements=["export_pdf", "sso"], # optional
)

if result.valid:
    print(f"License is valid: {result.code}")
    print(f"Entitlements: {result.entitlements}")
else:
    print(f"License invalid: {result.code}")

activate()

Activate a machine for a license. Authenticates using the license key (License scheme).

ParameterTypeRequiredDescription
keystrRequiredThe license key to activate against
fingerprintstrRequiredUnique machine fingerprint (min 8 characters)
namestr | NoneOptionalHuman-readable machine name
platformstr | NoneOptionalPlatform: "macos", "windows", "linux", "docker", or "kubernetes"

Returns a Machine record.

activate.py
machine = client.activate(
    key="MYAPP-XXXX-XXXX-XXXX-XXXX",
    fingerprint="abc123def456",
    name="Developer Workstation",        # optional
    platform="macos",                    # optional: macos, windows, linux, docker, kubernetes
)

print(f"Machine activated: {machine.id}")
print(f"Fingerprint: {machine.fingerprint}")

deactivate()

Deactivate (remove) a machine from a license to free up a device slot.

ParameterTypeRequiredDescription
machine_idstrRequiredUUID of the machine to deactivate
keystrRequiredThe license key the machine belongs to
deactivate.py
# Release the device slot (useful for floating licenses)
client.deactivate(
    machine_id="machine-uuid-here",
    key="MYAPP-XXXX-XXXX-XXXX-XXXX",
)

heartbeat()

Send a heartbeat for an active machine. Required when the policy has requireHeartbeat enabled.

ParameterTypeRequiredDescription
machine_idstrRequiredUUID of the machine to heartbeat
keystrRequiredThe license key the machine belongs to
heartbeat.py
# Send a heartbeat to keep the machine alive
client.heartbeat(
    machine_id="machine-uuid-here",
    key="MYAPP-XXXX-XXXX-XXXX-XXXX",
)

# Typical heartbeat loop
import time

while True:
    client.heartbeat(machine_id=machine.id, key=license_key)
    time.sleep(300)  # every 5 minutes

checkout()

Check out an Ed25519-signed offline license file. Authenticates using the API key (Bearer scheme).

ParameterTypeRequiredDescription
license_idstrRequiredUUID of the license to check out
fingerprintstrRequiredMachine fingerprint to bind the file to
ttlintOptionalTime-to-live in seconds. Defaults to 1209600 (14 days)

Returns a LicenseFile with the certificate and metadata.

checkout.py
# Download an Ed25519-signed offline license file
license_file = client.checkout(
    license_id="license-uuid-here",
    fingerprint="abc123def456",
    ttl=1209600,  # 14 days (default)
)

print(f"Certificate: {license_file.certificate}")
print(f"TTL: {license_file.ttl} seconds")

Response Models

ModelKey FieldsReturned By
ValidationResultvalid, code, license, machine, entitlementsvalidate()
Machineid, fingerprint, name, platform, heartbeat_statusactivate(), heartbeat()
Licenseid, status, product_id, policy_id, expires_atNested in ValidationResult
LicenseFilecertificate, license, fingerprint, ttlcheckout()

Error Handling

All SDK errors inherit from LicentricError. Each HTTP error status maps to a specific exception class.

ExceptionHTTP StatusWhen
AuthenticationError401Invalid or missing API key / license key
ValidationError400Invalid request parameters
NotFoundError404Resource does not exist
RateLimitError429Too many requests (includes retry_after)
LicentricErrorOtherBase class for all other API errors
errors.py
from licentric.exceptions import (
    LicentricError,
    AuthenticationError,
    ValidationError,
    NotFoundError,
    RateLimitError,
)

try:
    result = client.validate("MYAPP-XXXX-XXXX-XXXX-XXXX")
except AuthenticationError as e:
    print(f"Auth failed: {e.message}")        # HTTP 401
except ValidationError as e:
    print(f"Bad request: {e.message}")         # HTTP 400
    print(f"Details: {e.details}")
except NotFoundError as e:
    print(f"Not found: {e.message}")           # HTTP 404
except RateLimitError as e:
    print(f"Rate limited, retry after {e.retry_after}s")  # HTTP 429
except LicentricError as e:
    print(f"API error {e.status_code}: {e.message}")
    print(f"Code: {e.code}")