Validate a key
Validate a license key for a given device. This is the hot path — it is served from Cloudflare’s edge KV cache and returns in under 10ms on cache hits.
Endpoint
POST /v1/validateRequired permission: validate
Request
{ "key": "MYAPP-ABCD-EFGH-IJKL", "device_fingerprint": "sha256_of_stable_device_id", "app_version": "1.2.0"}| Field | Type | Required | Description |
|---|---|---|---|
key | string | ✅ | The license key string |
device_fingerprint | string | ✅ | SHA-256 hash of the device’s stable identifier (machine ID, hardware ID, etc.) |
app_version | string | Your app’s version string — stored for analytics |
Response — valid key
{ "valid": true, "plan": "pro", "expires_at": "2027-08-16T12:00:00Z", "activations_used": 1, "activation_limit": 3}| Field | Type | Description |
|---|---|---|
valid | boolean | Whether the key is valid for this device |
plan | string | null | The plan tier this key grants |
expires_at | string | null | ISO 8601 expiry; null for perpetual licenses |
activations_used | integer | Number of unique devices currently activated |
activation_limit | integer | Maximum concurrent activations allowed |
Response — invalid key
{ "valid": false, "reason": "revoked"}| Reason | Description |
|---|---|
not_found | Key does not exist in this account |
revoked | Key has been revoked |
expired | Key has passed its expires_at date |
activation_limit | Key has reached its activation limit on other devices |
Caching behavior
Lizen caches validation responses in Cloudflare KV with a 60-second TTL. On cache hits, the request never reaches the origin — latency is under 1ms at the nearest PoP.
Cache is invalidated immediately on revocation. After revoking a key, all subsequent validate calls return valid: false within milliseconds.
Example
import { Lizen } from '@lizen/sdk';
const lizen = new Lizen({ apiKey: process.env.LIZEN_API_KEY! });
const result = await lizen.validate({ key: storedLicenseKey, deviceFingerprint: getMachineId(),});
if (!result.valid) { // result.reason: 'not_found' | 'revoked' | 'expired' | 'activation_limit' showLicenseError(result.reason); app.quit();}Rate limits
| Plan | Calls/day |
|---|---|
| Free | 500 |
| Hobby | 10,000 |
| Starter | 50,000 |
| Growth | 200,000 |
| Enterprise | Unlimited |
Exceeded rate limits return 429 with a retry_after value in seconds.