Licensing Server

Use /validate from your apps to verify a license and receive a short-lived token. A single license may be used across multiple devices (limit is configurable).

Endpoints

How to embed checks

Docker apps

# In your container entrypoint or start script (bash)
LICENSE_KEY="YOUR-LICENSE-KEY"
DEVICE_ID=$(hostname)  # or a stable machine id

RESP=$(curl -s -X POST http://YOUR-SERVER/validate   -H "Content-Type: application/json"   -d "{\"product_type\":\"docker\",\"license_key\":\"$LICENSE_KEY\",\"device_id\":\"$DEVICE_ID\"}")

VALID=$(echo "$RESP" | jq -r .valid)
if [ "$VALID" != "true" ]; then
  echo "License invalid: $RESP" && exit 1
fi

TOKEN=$(echo "$RESP" | jq -r .access_token)
# Export for your app to use if needed:
export LICENSE_BEARER="$TOKEN"
  

Tkinter (Python)

import requests, uuid
device_id = str(uuid.getnode())  # or your own stable id
r = requests.post("http://YOUR-SERVER/validate", json={
    "product_type":"tkinter",
    "license_key":"YOUR-LICENSE-KEY",
    "device_id":device_id
}, timeout=5)
data = r.json()
if not data.get("valid"):
    raise SystemExit(f"License invalid: {data}")
token = data["access_token"]
# store in memory; re-validate every app start (or hourly)

Android (Kotlin + Retrofit)

// build.gradle: add Retrofit/OkHttp, Kotlinx-serialization or Moshi

data class ValidateReq(val product_type: String, val license_key: String, val device_id: String)
data class ValidateRes(val valid: Boolean, val access_token: String?)

interface LicApi {
  @POST("/validate") suspend fun validate(@Body req: ValidateReq): ValidateRes
}

// Usage:
val deviceId = Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)
val res = api.validate(ValidateReq("android", YOUR_LICENSE_KEY, deviceId))
if (!res.valid) { /* block app features / show error */ }
val bearer = res.access_token // use as needed

Admin Tips

Offline Grace

Clients can keep working without internet for OFFLINE_GRACE_MIN minutes after a successful validation, by caching the last good token timestamp.