License Verification Server licenseverificationserver.com
Sign In Get Started

API Reference

The License Verification Server API lets you activate, verify, deactivate, and manage software licenses programmatically. All tenant API calls are scoped to your account — you can only see your own products, licenses, and customers.

Authentication

Every API request must include an Authorization header with your tenant API key as a Bearer token.

Authorization: Bearer YOUR_TENANT_API_KEY

Generate API keys in your Developer Portal → API Keys. Keep your keys secret — they grant full access to your tenant data. Revoke any key that may have been exposed.

Base URL

https://www.licenseverificationserver.com

All endpoints are served over HTTPS. HTTP requests are rejected.

Endpoints

GET /api/v1/pubkey No auth required

Returns the server's Ed25519 public key. Bundle this key with your client software to verify license tokens offline.

Response

{ "alg": "ed25519", "kid": "abc123", "public_key": "base64url-encoded-public-key" }
POST /api/v1/activate

Activate a license on a device. Returns a signed JWT license token the client can cache and verify offline. Enforces seat limits — if the seat limit is reached, returns 409 Conflict.

Request body

FieldTypeRequiredDescription
license_keystringrequiredThe license key to activate
product_idstringrequiredYour product's unique ID
machine_idstringrequiredUnique device identifier (hash of hardware fingerprint, UUID, etc.)
machine_namestringoptionalHuman-readable device name for the admin dashboard
curl -X POST https://www.licenseverificationserver.com/api/v1/activate \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "license_key": "XXXX-YYYY-ZZZZ", "product_id": "my-app", "machine_id": "device-fingerprint-hash", "machine_name": "Work Laptop" }'
import requests resp = requests.post( "https://www.licenseverificationserver.com/api/v1/activate", headers={"Authorization": "Bearer YOUR_API_KEY"}, json={ "license_key": "XXXX-YYYY-ZZZZ", "product_id": "my-app", "machine_id": "device-fingerprint-hash", "machine_name": "Work Laptop", }, ) data = resp.json() token = data["token"] # cache this locally
const res = await fetch( "https://www.licenseverificationserver.com/api/v1/activate", { method: "POST", headers: { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ license_key: "XXXX-YYYY-ZZZZ", product_id: "my-app", machine_id: "device-fingerprint-hash", machine_name: "Work Laptop", }), } ); const { token, license } = await res.json();

Response

{ "ok": true, "token": "eyJ...(signed JWT)", "license": { "key": "XXXX-YYYY-ZZZZ", "product_id": "my-app", "tier": "standard", "seat_limit": 2, "seats_used": 1, "status": "active", "expires_at": "2027-01-01T00:00:00Z", "features": {} } }
POST /api/v1/verify

Verify a license and get a fresh signed token. Called periodically to refresh the cached token (e.g. every 7 days) and check for revocations or expirations. Requires an active activation on the device.

Request body

FieldTypeRequiredDescription
license_keystringrequired*Required unless a valid token is provided
machine_idstringrequiredDevice identifier
tokenstringoptionalExisting cached token — key/product are extracted from it if present
curl -X POST https://www.licenseverificationserver.com/api/v1/verify \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"license_key":"XXXX-YYYY-ZZZZ","machine_id":"device-hash"}'
POST /api/v1/deactivate

Deactivate a license on a specific device, freeing up a seat. Call this when the user uninstalls or explicitly deactivates your software.

curl -X POST https://www.licenseverificationserver.com/api/v1/deactivate \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"license_key":"XXXX-YYYY-ZZZZ","machine_id":"device-hash"}'

Response

{"ok": true}
POST /api/v1/heartbeat

Touch the activation's last_seen_at timestamp. Send periodically (e.g. hourly) while the software is running to keep the activation record fresh. Returns 403 if the device is not activated or has been blocked.

curl -X POST https://www.licenseverificationserver.com/api/v1/heartbeat \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"license_key":"XXXX-YYYY-ZZZZ","machine_id":"device-hash"}'
{"ok": true}

Error Codes

HTTP StatusMeaning
400Bad request — missing or invalid fields
401Unauthorized — missing, invalid, or expired API key
403Forbidden — license revoked, suspended, expired, or device blocked
404Not found — unknown license key
409Conflict — seat limit reached
429Too many requests — rate limit or transfer limit exceeded

All error responses are JSON: {"ok": false, "error": "description"}

Rate Limits

The API does not impose a fixed rate limit per tenant at this time. Fair-use policies apply. Abusive traffic (bulk activations, scanning, credential stuffing) will result in account suspension. Client programs should not call verify or heartbeat more than once per minute per device.

Questions? Go to your portal or view pricing.