One Platform to License, Protect & Monetize Your Software.
ScaleGate gives independent software vendors a complete white-labelled licensing engine. Issue keys, enforce device limits, accept payments and track revenue, all under your own brand.
License keys issued automatically on payment confirmation
Activate on desktop (WPF/WinForms) via .NET SDK
Activate web apps via domain fingerprinting
Manage registered devices and free slots remotely
Download app binaries with license pre-configured
Offline grace period (configurable days) during connectivity loss
View payment history and download PDF invoices
Everything a Software Vendor Needs
Built to cover the complete ISV lifecycle, from first app to enterprise scale, under your own brand.
🎨
White-Label Branding
Custom logo, colours, fonts, and CSS. Your customers never see ScaleGate. They see you.
🌐
Custom Domains + SSL
Point your own domain (e.g., licenses.yourbrand.com). ULS auto-provisions Let's Encrypt TLS with zero configuration.
💳
PesaPal Payments
Accept KES payments natively. Invoices generated as PDF. Revenue share disbursed automatically to your merchant account.
🔑
License Lifecycle Management
Issue, override, extend, and revoke keys in seconds. Bulk operations supported. Full status history per license.
🖥
Desktop SDK (.NET)
Drop the Licensing.SDK NuGet package into any WPF or WinForms app. Activate, validate, auto-update, and revoke in five lines of code.
🌍
Web License API
Six REST endpoints for web and SaaS apps. Domain fingerprinting, feature flags, server-to-server validation, and heartbeat checks.
🛡
Role-Based Access Control
16 granular permissions. Custom roles. MasterAdmin bypass. Every access decision is audited.
📊
Revenue Dashboard
Real-time MRR, active licenses, device counts, and customer activity, all in your white-labelled portal.
📱
Device Management
Enforce per-plan device limits. Customers manage their own devices. Admins can override remotely.
⚡
Feature Flags by Plan
Ship one codebase. Unlock features based on the customer's plan tier: SSO, API access, analytics, and more.
🔄
JWT Key Rotation
Rotate your tenant signing key on demand. All existing sessions are immediately invalidated.
📋
Audit Logs
20+ action types logged with IP address, user agent, actor identity, and full metadata. Compliance-ready.
Two SDKs. Every Platform.
Production-ready client libraries for desktop and web. Activate, validate, enforce, and auto-update with real API calls.
The ScaleGate.Licensing.SDK (.NET Standard 2.0) targets WPF and WinForms with hardware fingerprinting, offline caching, and self-update. The @scalegate/licensing-web-sdk (TypeScript) covers browser apps, React SPAs, and Node.js backends with domain fingerprinting and server-to-server validation.
.NET📦dotnet add package ScaleGate.Licensing.SDK
npm📦npm i @scalegate/licensing-web-sdk
WPF Desktop Application
.NET Standard 2.0NuGet
Install Licensing.SDK via NuGet. The builder pattern configures your API URL, offline cache, grace period, and auto-revalidation -then activates the device with a single async call. Hardware fingerprinting (CPU + motherboard + machine SID, SHA-256 hashed) is automatic.
Identical SDK, different UI framework. The LicenseClient is framework-agnostic -events marshal back to the UI thread using Invoke(). Activation, validation, revocation, and auto-update work identically to WPF.
Program.cs -Entry Point Guard
using Licensing.SDK;
static classProgram
{
internal staticLicenseClient? License;
[STAThread]
static asyncTaskMain()
{
ApplicationConfiguration.Initialize();
var key = Settings.Default.LicenseKey;
if (string.IsNullOrEmpty(key))
{
using var dlg = newActivationForm();
if (dlg.ShowDialog() != DialogResult.OK)
return;
key = dlg.LicenseKey;
}
License = awaitLicenseClient
.Create("my-winforms-app", key)
.WithApiUrl("https://acme.scalegate.io")
.WithOfflineValidation(true)
.WithGracePeriod(7)
.WithAutoRevalidation(true, 60)
.BuildAndActivateAsync();
if (!License.IsValid)
{
MessageBox.Show(
License.CurrentStatus.Message,
"License Error");
return;
}
Application.Run(newMainForm());
}
}
MainForm.cs -Status Bar & Deactivation
public partial classMainForm : Form
{
publicMainForm()
{
InitializeComponent();
var lic = Program.License!;
var s = lic.CurrentStatus!;
// Show license info in status strip
lblPlan.Text = $"Plan: {s.PlanName}";
lblDevices.Text =
$"Devices: {s.ActiveDevices}/{s.MaxDevices}";
lblExpiry.Text =
$"Expires: {s.ExpiryDate:MMM dd, yyyy}";
// Warn on grace period
lic.LicenseStatusChanged += (_, e) =>
{
Invoke(() =>
{
if (e.NewStatus == LicenseStatus.GracePeriod)
warningPanel.Visible = true;
if (e.NewStatus == LicenseStatus.Expired)
{
MessageBox.Show("License expired.");
Close();
}
});
};
}
// Deactivate on uninstall / sign-outprivate async voidbtnDeactivate_Click(
object s, EventArgs e)
{
var result = awaitProgram.License!
.RevokeAsync();
if (result.IsValid)
{
Program.License.Dispose();
Settings.Default.LicenseKey = "";
Settings.Default.Save();
Application.Restart();
}
}
}
WinForms.NET 8 / 9.NET Framework 4.6.1+Offline CacheDevice RevocationGrace Period
TypeScript / JavaScript
npmESM + CJS
Install @scalegate/licensing-web-sdk from npm. The client auto-detects browser vs. server mode, registers the domain or IP, and starts periodic validation with configurable callbacks for invalid/valid transitions.
Initialisation & Validation
import { LicenseClient } from'@scalegate/licensing-web-sdk';
// Create and initialise the clientconst client = newLicenseClient({
apiUrl: 'https://acme.scalegate.io',
licenseKey: 'XXXX-XXXX-XXXX-XXXX',
appId: 'my-saas-app',
mode: 'web', // 'web' = browser, 's2s' = server
validateInterval: 300000, // 5 min periodic check
onInvalid: (status) => {
console.error(`License invalid: ${status.message}`);
showPaywall();
},
onValid: (status) => {
console.log(`License OK -${status.daysRemaining}d left`);
},
});
// Register this domain and start validation loopconst status = await client.initialise();
if (status.isValid) {
console.log(`Plan: ${status.planName}`);
console.log(`Domains: ${status.activeDomains}/${status.maxDomains}`);
}
Feature Flags & Status
// Check which features the plan unlocksconst features = await client.checkFeatures(
['sso', 'api_access', 'analytics', 'white_label']
);
if (features.valid) {
console.log(`Plan: ${features.planName}`);
if (features.features.sso)
enableSSOLogin();
if (features.features.analytics)
loadAnalyticsDashboard();
}
// Full status with registered domainsconst detail = await client.getStatus();
console.log(detail.currentDomainRegistered);
console.log(detail.registeredDomains);
console.log(detail.featureFlags);
// Lightweight heartbeat (returns boolean)const alive = await client.heartbeat();
// Cached status (no network call)const cached = client.getCachedStatus();
// Cleanup on unmount / shutdown
client.destroy();
🌐
Domain Fingerprint
Automatic Origin header detection in browser mode
⚡
Feature Flags
Check plan-gated features with one API call
🔁
Periodic Validation
Configurable interval with onValid/onInvalid callbacks
🔒
Dual Mode
'web' for browsers, 's2s' for server-to-server with IP
getCachedStatus() returns last result without network call
onValid / onInvalid callbacks for periodic validation events
LicenseError class with httpStatus and licenseStatus properties
destroy() stops interval and cleans up resources
Full TypeScript definitions included (.d.ts)
React Integration
React 18/19Hooks
Wrap the Web SDK in a React context provider and a custom hook. The provider initialises the license on mount, cleans up on unmount, and exposes status + feature flags to every component in your tree.
Use mode: 's2s' for server-side validation. The SDK sends the server's IP address instead of the browser Origin header. Ideal for protecting API backends, microservices, and server-rendered apps.
Don't use .NET or JavaScript? Call the licensing API directly from any language. All endpoints accept and return JSON. Desktop endpoints use hardware fingerprints; web endpoints use domain or IP fingerprinting.
💻 Desktop SDK Endpoints
Method
Endpoint
Description
POST
/api/licenses/activate
Register a device with a license key. Sends appId, licenseKey, and hardware fingerprint. Returns full validation result.
POST
/api/licenses/validate
Validate a license. Returns isValid, status, expiry, plan name, device counts, and days remaining.
POST
/api/licenses/renew
Renew a license with a new plan ID. Updates expiry and plan details.
POST
/api/licenses/revoke
Deregister a device, freeing its slot for another machine.
POST
/api/licenses/check-update
Check if a newer binary version is available. Returns version, release notes.
POST
/api/licenses/download-token
Get a time-limited token for downloading an update binary from Azure Blob Storage.
🌐 Web SDK Endpoints
Method
Endpoint
Description
POST
/api/web-licenses/initialise
Register a domain with a web license. Browser mode uses Origin header for fingerprinting.
POST
/api/web-licenses/validate
Validate a web license from the browser. Returns status, plan, expiry, domain counts.
POST
/api/web-licenses/s2s/validate
Server-to-server validation using the server's IP address as fingerprint.
GET
/api/web-licenses/status/{key}
Full status detail: registered domains, feature flags, current domain registration, plan info.
POST
/api/web-licenses/features
Check which feature flags are enabled for a license's plan. Accepts array of feature keys.
GET
/api/web-licenses/heartbeat/{key}
Lightweight alive check -returns boolean. Use for fast polling without full validation overhead.
📋 License Status Values (Both SDKs)
ActiveValid and online-verified
GracePeriodExpired but within offline grace window