Quickstart
Get from zero to working license validation with the smallest possible set of correct steps.
Who This Is For
- developers integrating LicenseKit into an application for the first time
- teams evaluating the hosted API before committing to a deeper rollout
- operators who want a clear split between setup work and in-app runtime work
When To Use This
Use this page when you want a first success quickly.
If you are automating the setup with an AI agent, read Agent Quickstart immediately after this page. If you need the exact auth or scope model first, read Auth And Scopes.
How It Works
The fastest successful integration has two parts:
- use the management API once to create a product, policy, and license
- use the runtime API inside your app to validate that license and verify the signature
Recommended hosted base URL:
https://api.licensekit.devStep 1: Install the SDK
TypeScript is the shortest documented path in this rewrite set:
npm install @licensekit/sdkOther first-party SDKs are available for Python, Go, Ruby, and .NET. See SDK Overview.
Step 2: Create a product and policy
Use a management token with product:write and license:write, or bootstrap with admin.
import { ManagementClient } from "@licensekit/sdk";
const management = new ManagementClient({
baseUrl: "https://api.licensekit.dev",
token: process.env.LICENSEKIT_MANAGEMENT_TOKEN!
});
const product = await management.createProduct({
body: {
name: "Example App",
code: "example-app"
}
});
const policy = await management.createPolicy({
path: { id: product.data.id },
body: {
name: "Default Policy",
code: "default",
license_type: "perpetual"
}
});Step 3: Issue a license
const license = await management.createLicense({
body: {
product_id: product.data.id,
policy_id: policy.data.id,
customer_email: "[email protected]",
customer_name: "Example Developer"
}
});
console.log("License key:", license.data.license_key);Step 4: Validate the license in your app
import {
PublicKeyStore,
RuntimeClient,
SystemClient,
verifyRuntimeResult
} from "@licensekit/sdk";
const baseUrl = "https://api.licensekit.dev";
const licenseKey = process.env.LICENSE_KEY!;
const runtime = new RuntimeClient({ baseUrl, licenseKey });
const system = new SystemClient({ baseUrl });
const result = await runtime.validateLicense({
body: {
fingerprint: "host-123"
}
});
const publicKeys = await system.listPublicKeys();
const verification = await verifyRuntimeResult(
result,
new PublicKeyStore(publicKeys.data)
);
if (!verification.ok) {
throw new Error("signature verification failed");
}
if (!result.data.status || result.data.status !== "active") {
throw new Error(`license is not active: ${result.data.status}`);
}Step 5: Decide what comes next
- If you only need periodic entitlement checks, keep using
validateorcheck. - If you bind to specific machines, add device lifecycle handling.
- If you need quotas, add metering and feature assignments.
- If you need offline use, add offline issuance and local verification.
Self-hosted quickstart
If you need a local backend first, the current repo path is:
go test ./...
./bin/locksmith init
./bin/locksmith migrate up
./bin/locksmith serveUse your self-hosted origin as baseUrl instead of https://api.licensekit.dev.
Example
Minimal environment:
export LICENSEKIT_MANAGEMENT_TOKEN=...
export LICENSE_KEY=...Minimal outcome:
- management setup succeeds with
{data, meta}responses - runtime validation succeeds with
{data, signature, meta} - the runtime signature verifies against public keys from the system surface
Common Mistakes
- creating the license but validating it with a bearer token instead of
Authorization: License <license-key> - shipping runtime validation without checking the signature
- starting with an oversized
admintoken when a narrower scoped key would do - assuming the quickstart also covers reporting, webhooks, or deployment hardening