Unity SDK
Unity SDK
Unity 2021.2+ client (.NET Standard 2.1 API Compatibility Level), zero external package dependencies — no Newtonsoft.Json, no additional UPM packages. Works on Desktop, Mobile, and Console builds; WebGL works for online calls, with one crypto caveat noted below.
Download Unity SDK (ZIP)Installation
Not yet published as a UPM registry or git-URL package — extract the source ZIP above,
then in Unity: Window → Package Manager → + → Install package from
disk... and select the extracted folder's package.json. Or copy
Runtime/'s contents straight into your project's Assets/ folder.
Quick start — validate
using PermitCore;
using UnityEngine;
public class LicenseGate : MonoBehaviour
{
private PermitCoreClient _client;
async void Start()
{
_client = new PermitCoreClient("https://api.permitcore.dev");
var result = await _client.ValidateAsync("PERMIT-XXXX-XXXX-XXXX-XXXX");
if (!result.IsValid)
{
Debug.LogError("License invalid: " + result.Message);
return;
}
if (result.HasFeature("pro"))
EnableProFeatures();
}
}
Activate (call once per installation)
var result = await _client.ActivateAsync(
"PERMIT-XXXX-XXXX-XXXX-XXXX",
deviceId: null, // auto-generated when omitted
deviceName: SystemInfo.deviceName,
version: Application.version); // optional — enforces min/maxVersion
if (!result.IsValid)
Debug.LogError("Activation failed: " + result.Message);
Metered billing
await _client.MeterAsync(licenseKey, "level_completed");
await _client.MeterAsync(licenseKey, "export", quantity: 5,
meta: new Dictionary<string, object> { ["format"] = "png" });
Floating licenses
var session = await _client.CheckoutAsync(licenseKey);
if (!session.Success) { Debug.LogError("No seats available: " + session.Message); return; }
// Heartbeat every 4-5 minutes (e.g. from a coroutine or InvokeRepeating)
await _client.HeartbeatAsync(session.SessionToken);
// On quit / logout
await _client.CheckinAsync(session.SessionToken);
Offline license tokens
No extra package needed — System.Security.Cryptography.ECDsa is part of
Unity's .NET Standard 2.1 surface on Desktop, Mobile, and Console targets.
// Pure local verification — no network call, never throws on Desktop/Mobile/Console.
var result = PermitCoreClient.VerifyOfflineToken(token, publicKeyBase64);
if (result.IsValid)
Debug.Log("Valid! Product: " + result.Payload.ProductName);
// Bind to this device + persist locally (call once, e.g. at install time)
var activated = _client.ActivateOffline(token, publicKeyBase64, deviceId);
// On every later launch — no token needed, reads the local cache
var cached = _client.ValidateOffline(deviceId);
System.Security.Cryptography implementation, so the
three offline-token methods above will throw on that one platform. Online
ValidateAsync/ActivateAsync work fine on WebGL via
UnityWebRequest — only the fully-offline crypto path is affected, and
that's a platform constraint of WebGL itself, not something this SDK can work around.
Hardware ID
// Default: a random id persisted to a local file — works identically on every platform.
string hwid = _client.GetHardwareId();
// Unity-idiomatic alternative, recommended on mobile/console:
string hwid = UnityHardwareId.Get(); // SHA-256 of SystemInfo.deviceUniqueIdentifier
LicenseResult reference
| Field | Type | Description |
|---|---|---|
IsValid | bool | True if the license is active and valid |
ProductName | string | Product the license belongs to |
RemainingActivations | int? | Activation slots remaining |
ExpiresAt | string | ISO 8601 expiry date, null = perpetual |
Features | List<string> | Feature flag list, e.g. ["export","api"] |
IsTrial | bool | True for trial licenses |
TrialDaysRemaining | int? | Days until trial expires |
NodeLocked | bool | True if bound to a specific device |
OfflineGraceDays | int? | How many days the cache remains valid |
MinVersion / MaxVersion | string | Version enforcement bounds |
VendorWarning | string | Non-fatal message from the vendor |
Message | string | Reason when IsValid == false |
IsOffline | bool | True when result came from local cache |
ErrorCode | string | Stable, machine-readable failure reason |
HasFeature(string feature) — case-insensitive feature check.