REST API for generating, validating and tracking activation keys. Works from any language — SaaS apps, desktop apps, scripts.
https://your-app/api/public/v1Public endpoints (/validate, /activate) do not require auth — they accept a key and return its status.
Owner endpoints (/generate, /keys) require your personal API token in the X-API-Token header. Get it from your dashboard.
X-API-Token: <your-api-token>/api/public/v1/activateActivate a key on a machine. The first time a (key, machine_id) pair is seen, it counts against max_uses. Subsequent calls from the same machine are idempotent (no extra usage charged).
{
"key": "K7M2PQ-4XJN8R-9BVH3W-T6YDFC",
"machine_id": "desktop-abc-123" // any stable per-machine identifier
}{
"valid": true,
"status": "active",
"software_name": "MyApp Pro",
"expires_at": "2026-12-31T23:59:59.000Z",
"use_count": 1,
"max_uses": 3,
"first_used_at": "2026-06-03T12:00:00.000Z",
"activated": true // true if a new activation was recorded
}{ "valid": false, "reason": "expired" }
// possible reasons: not_found, revoked, expired, exhaustedcurl -X POST https://your-app/api/public/v1/activate \
-H "Content-Type: application/json" \
-d '{"key":"K7M2PQ-4XJN8R-9BVH3W-T6YDFC","machine_id":"desktop-abc-123"}'const res = await fetch("https://your-app/api/public/v1/activate", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ key: userKey, machine_id: getMachineId() }),
});
const data = await res.json();
if (!data.valid) showError(data.reason);import requests, uuid
machine_id = str(uuid.getnode())
r = requests.post("https://your-app/api/public/v1/activate",
json={"key": user_key, "machine_id": machine_id})
data = r.json()
if not data["valid"]:
raise SystemExit(f"License invalid: {data['reason']}")/api/public/v1/validateLightweight read-only check. Does not create an activation or change usage counters. Use it from a SaaS app on every request to verify the key is still good.
{ "key": "K7M2PQ-4XJN8R-9BVH3W-T6YDFC" }{
"valid": true,
"status": "active",
"software_name": "MyApp Pro",
"expires_at": "2026-12-31T23:59:59.000Z",
"use_count": 2,
"max_uses": 3,
"first_used_at": "2026-06-03T12:00:00.000Z"
}curl -X POST https://your-app/api/public/v1/validate \
-H "Content-Type: application/json" \
-d '{"key":"K7M2PQ-4XJN8R-9BVH3W-T6YDFC"}'/api/public/v1/generateGenerate a new activation key. Requires your API token. Useful for automating key issuance from your billing system or admin tools.
X-API-Token: <your-api-token>
Content-Type: application/json{
"software_name": "MyApp Pro",
"max_uses": 1, // optional, default 1
"expires_at": "2026-12-31T23:59:59Z", // optional ISO date
"notes": "Order #1234" // optional
}{
"key": "K7M2PQ-4XJN8R-9BVH3W-T6YDFC",
"software_name": "MyApp Pro",
"max_uses": 1,
"expires_at": "2026-12-31T23:59:59.000Z",
"created_at": "2026-06-03T12:00:00.000Z"
}curl -X POST https://your-app/api/public/v1/generate \
-H "X-API-Token: $KEYFORGE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"software_name":"MyApp Pro","max_uses":3}'/api/public/v1/keysList all keys owned by the API token holder.
curl https://your-app/api/public/v1/keys -H "X-API-Token: $KEYFORGE_TOKEN"For every activation, KeyForge stores:
machine_id)The license itself tracks first_used_at, last_used_at, last_used_ip, use_count, max_uses, expires_at.
not_found — key doesn't existrevoked — key was revoked by ownerexpired — key past its expiration dateexhausted — key already used max_uses times on different machines