API Documentation

LicenseKit provides a simple REST API to implement software license verification in any language or platform.

Base URL: https://api.saaslic.com   All endpoints return standard JSON over HTTPS.

Quick Start

Integrate LicenseKit in three steps:

1. Register and get your API Key

Sign up at Dashboard, create a project, then generate your API key from the top-right corner.

2. Create a license

Create licenses manually in the Dashboard under Licenses, or generate them in bulk via the API, then distribute them to your users.

3. Call the verify endpoint in your app

curl -X POST https://api.saaslic.com/api/license/verify \
  -H "Content-Type: application/json" \
  -d '{
    "license_key": "LIC-XXXXXXXX-XXXX",
    "project_code": "YOUR_PROJECT_CODE",
    "device_id": "unique-device-identifier"
  }'

Authentication

Endpoints that require login (create / delete / list) use Bearer Token authentication. Pass your token in the request header:

Authorization: Bearer YOUR_JWT_TOKEN

The verify endpoint (POST /api/license/verify) does not require authentication — call it directly from your client application.


Verify License

POST /api/license/verify

Verify a license key and bind the device if not already bound. No authentication required — safe to call from client apps.

Request Parameters

FieldTypeRequiredDescription
license_keystringLicense key, format LIC-XXXXXXXX-XXXX
project_codestringProject code, found in Dashboard project settings
device_idstringUnique device identifier — use hardware fingerprint or UUID
device_namestring-Device name, e.g. "MacBook Pro"
platformstring-Platform, e.g. "macOS" / "Windows"

Success Response

{
  "ok": true,
  "session_token": "eyJ...",
  "license": {
    "project_name": "MyApp",
    "project_code": "MY_APP",
    "license_key": "LIC-MMKFFCBQ-D37J",
    "expire_at": null,
    "max_devices": 1
  }
}

Error Response

{
  "ok": false,
  "message": "License invalid"
}

Code Examples

curl
Python
Node.js
curl -X POST https://api.saaslic.com/api/license/verify \
  -H "Content-Type: application/json" \
  -d '{
    "license_key": "LIC-XXXXXXXX-XXXX",
    "project_code": "MY_APP",
    "device_id": "my-device-001"
  }'
import requests

resp = requests.post(
    "https://api.saaslic.com/api/license/verify",
    json={
        "license_key": "LIC-XXXXXXXX-XXXX",
        "project_code": "MY_APP",
        "device_id": "my-device-001",
    }
)
data = resp.json()

if data["ok"]:
    print("Verified:", data["license"]["project_name"])
else:
    print("Failed:", data["message"])
const res = await fetch("https://api.saaslic.com/api/license/verify", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    license_key: "LIC-XXXXXXXX-XXXX",
    project_code: "MY_APP",
    device_id: "my-device-001",
  }),
});
const data = await res.json();

if (data.ok) {
  console.log("Verified:", data.license.project_name);
} else {
  console.log("Failed:", data.message);
}

Create License

POST /api/license/create

Create a single license key. Requires Bearer Token authentication.

Request Parameters

FieldTypeRequiredDescription
project_idnumberProject ID
expire_atstring-Expiry date in YYYY-MM-DD format. Omit for lifetime license.
max_devicesnumber-Max devices allowed. Defaults to 1.
customer_emailstring-If provided, sends the license key to this email automatically.

Response

{
  "ok": true,
  "message": "License created successfully",
  "license": {
    "id": 10,
    "license_key": "LIC-MMQ75CC5-JVQV",
    "expire_at": null,
    "max_devices": 1
  }
}

List Licenses

GET /api/license/list

Returns all licenses for the authenticated account. Supports filtering by project. Requires Bearer Token.

Query Parameters

FieldTypeDescription
project_idnumberFilter by project. Returns all if omitted.

Delete License

DEL /api/license/:id

Deletes a license and all its bound device records. Requires Bearer Token.


List Devices

GET /api/devices

Returns all bound devices for the authenticated account. Requires Bearer Token.

Query Parameters

FieldTypeDescription
license_idnumberFilter by license

Unbind Device

DEL /api/devices/:id

Unbinds a device from its license. The device can then be rebound to another license. Requires Bearer Token.


Error Codes

HTTP StatusmessageDescription
400Missing required fieldsIncomplete request parameters
401Token invalid or expiredBearer Token missing or expired
400License invalidLicense expired, disabled, or device limit reached
404License not foundIncorrect license_key or project_code
500Server errorContact [email protected]

Python SDK

Skip the HTTP boilerplate — verify licenses in one line with automatic device fingerprinting.

Install

pip install saaslic

📦 Source: github.com/why5353/saaslic-sdk

Usage

from saaslic import LicenseKit

lk = LicenseKit("YOUR_PROJECT_CODE")

# Full response
result = lk.verify("LIC-XXXXXXXX-XXXX")
if result["ok"]:
    print("Verified:", result["license"]["project_name"])
else:
    print("Failed:", result["message"])

# Simple check
if lk.check("LIC-XXXXXXXX-XXXX"):
    print("License valid — launching app")

PyPI: pypi.org/project/saaslic


Node.js SDK

Zero dependencies — verify licenses in one line with automatic device fingerprinting.

Install

npm install saaslic

📦 Source: github.com/why5353/saaslic-sdk

Usage

const { LicenseKit } = require("saaslic");

const lk = new LicenseKit("YOUR_PROJECT_CODE");

// Full response
const result = await lk.verify("LIC-XXXXXXXX-XXXX");
if (result.ok) {
  console.log("Verified:", result.license.project_name);
} else {
  console.log("Failed:", result.message);
}

// Simple check
if (await lk.check("LIC-XXXXXXXX-XXXX")) {
  console.log("License valid — launching app");
}

npm: npmjs.com/package/saaslic


Full Integration Example

A complete example of verifying a license at startup in a Python desktop app:

import requests
import hashlib
import platform
import sys

def get_device_id():
    raw = platform.node() + platform.processor()
    return hashlib.md5(raw.encode()).hexdigest()

def verify_license(license_key: str) -> bool:
    try:
        resp = requests.post(
            "https://api.saaslic.com/api/license/verify",
            json={
                "license_key": license_key,
                "project_code": "MY_APP",
                "device_id": get_device_id(),
                "device_name": platform.node(),
                "platform": platform.system(),
            },
            timeout=5
        )
        data = resp.json()
        if data["ok"]:
            print(f"License valid — welcome to {data['license']['project_name']}")
            return True
        else:
            print(f"License invalid: {data['message']}")
            return False
    except Exception as e:
        print(f"Network error: {e}")
        return False

key = input("Enter your license key: ")
if not verify_license(key):
    sys.exit(1)