FSK Guard

REST API v1

License API Documentation

Use FSK Guard to verify license keys, bind domains and devices, issue offline tokens, and return feature flags to client software.

Base URL

https://fskguard.fskhangar.com/api/v1

Format

JSON requests and responses

Authentication

Product ID + Product Secret headers

Authentication

Every API request must include the product credentials generated in the product detail page.

X-Product-ID: fsk-stock
X-Product-Secret: sk_your_secret_token
Content-Type: application/json
Accept: application/json
Keep `X-Product-Secret` server-side when possible. For desktop apps, treat it as a piracy-reduction secret, rotate it periodically, and rely on device limits, logs, and offline token expiry for abuse control.
POST

/api/v1/license/verify

Checks whether a license is valid for the product, domain, device, expiry, status, and limits. Returns feature flags and a signed runtime token.

{
  "license_key": "FSK-8KJD-92KD-LM3X-PQ7A",
  "domain": "example.com",
  "device_fingerprint": "hashed-device-id",
  "platform": "desktop",
  "version": "1.0.0"
}
{
  "success": true,
  "status": "active",
  "message": "License is valid.",
  "license": {
    "type": "lifetime",
    "expires_at": null,
    "max_devices": 3,
    "max_domains": 1,
    "allowed_features": ["inventory", "reports"]
  },
  "token": "signed-runtime-token"
}

Feature flags

Use `license.allowed_features` to enable modules in your app. Missing features should be treated as disabled.

Runtime token

The `token` is a signed short-lived proof that the latest online verification succeeded.

POST

/api/v1/license/activate

Use during first install. If allowed, the domain and/or device becomes linked to the license and activation logs are created.

{
  "license_key": "FSK-XXXX-XXXX-XXXX",
  "domain": "example.com",
  "device_fingerprint": "hashed-device-id",
  "platform": "electron",
  "version": "2.4.1"
}
POST

/api/v1/license/deactivate

Use when a customer removes an installation or moves to another device/domain.

{
  "license_key": "FSK-XXXX-XXXX-XXXX",
  "device_fingerprint": "hashed-device-id"
}
POST

/api/v1/license/offline-token

Issues a signed JWT for activated desktop devices. Suggested durations: trial 1 day, monthly 3 days, yearly 7 days, lifetime 30 days.

{
  "success": true,
  "offline_token": "jwt-token"
}
License type Offline duration
trial1 day
monthly3 days
yearly7 days
lifetime30 days

Error Responses

Failed checks return HTTP `422` for license decision failures and `401/403` for authentication or workspace suspension.

{
  "success": false,
  "status": "domain_mismatch",
  "message": "This license is not valid for this domain."
}
invalid_licenseLicense key was not found.
expiredLicense expiration date is in the past.
suspendedOwner suspended the license.
revokedLicense was permanently revoked.
domain_mismatchDomain does not match active domains.
device_limit_exceededNo free device slots remain.
activation_limit_exceededActivation count limit was reached.

Try a Request

Send a real request to this FSK Guard instance. Use credentials from a product detail page.

Browser request

Code Examples

cURL

curl -X POST "https://fskguard.fskhangar.com/api/v1/license/verify" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "X-Product-ID: fsk-stock" \
  -H "X-Product-Secret: sk_your_secret" \
  -d '{"license_key":"FSK-XXXX-XXXX-XXXX","domain":"example.com"}'

PHP SDK

$guard = new FskGuard([
    'license_key' => getenv('FSK_GUARD_LICENSE_KEY'),
    'product_id' => getenv('FSK_GUARD_PRODUCT_ID'),
    'product_secret' => getenv('FSK_GUARD_PRODUCT_SECRET'),
    'api_url' => 'https://fskguard.fskhangar.com',
]);

$result = $guard->verify(['domain' => 'example.com']);

if (! $result->success) {
    die($result->message);
}

Laravel Middleware

// config/fskguard.php
return [
    'license_key' => env('FSK_GUARD_LICENSE_KEY'),
    'product_id' => env('FSK_GUARD_PRODUCT_ID'),
    'product_secret' => env('FSK_GUARD_PRODUCT_SECRET'),
    'api_url' => env('FSK_GUARD_API_URL'),
];

Route::middleware(['fsk.guard'])->group(function () {
    Route::get('/admin', AdminController::class);
});

JavaScript / Electron

const result = await activateLicense({
  apiUrl: 'https://fskguard.fskhangar.com',
  productId: process.env.FSK_GUARD_PRODUCT_ID,
  productSecret: process.env.FSK_GUARD_PRODUCT_SECRET,
  licenseKey,
  appVersion: app.getVersion()
});

if (!result.success) throw new Error(result.message);

Python

client = FskGuardClient(
    api_url='https://fskguard.fskhangar.com',
    product_id=os.getenv('FSK_GUARD_PRODUCT_ID'),
    product_secret=os.getenv('FSK_GUARD_PRODUCT_SECRET'),
)

result = client.activate(license_key)

if not result.get('success'):
    raise RuntimeError(result.get('message'))

.NET

var client = new FskGuardClient(
    "https://fskguard.fskhangar.com",
    Environment.GetEnvironmentVariable("FSK_GUARD_PRODUCT_ID"),
    Environment.GetEnvironmentVariable("FSK_GUARD_PRODUCT_SECRET")
);

var result = await client.ActivateAsync(licenseKey, "1.0.0");

if (result?.Success != true)
    throw new Exception(result?.Message);

Webhooks

Configure endpoints in Settings. FSK Guard signs every delivery with HMAC-SHA256.

license.created
license.activated
license.expired
license.suspended
license.revoked
device.activated
suspicious.activity.detected
integration.purchase.approved

SDKs and Examples

The repository includes installable package skeletons and ready-to-copy desktop examples.

PHP SDK

Path: packages/php-sdk

composer require fsk-guard/php-sdk

Laravel Package

Path: packages/laravel-fsk-guard

Route::middleware('fsk.guard')

Desktop Examples

Path: examples/desktop

Python, Electron, Tauri and .NET samples.

Webhooks

Create endpoints in Settings and verify `X-FSK-Signature`.