PHP SDK
Official SDKs
PHP SDK
Pure PHP 8.0+ client. Enable ext-curl and ext-json for online calls, and ext-openssl for offline verification. No Guzzle, no additional packages. Works with Laravel, Symfony, WordPress plugins, raw PHP scripts.
Download PHP SDK (ZIP)Installation via Composer
composer require permitcore/sdk
Or install from the downloaded source ZIP:
unzip permitcore-sdk-php.zip -d permitcore-sdk-php
# Then in composer.json add the path repository:
composer config repositories.local path ../permitcore-sdk-php
composer require permitcore/sdk:@dev
Quick start — validate
<?php
require 'vendor/autoload.php';
use PermitCore\PermitCoreClient;
$client = new PermitCoreClient('https://api.permitcore.dev');
$result = $client->validate('PERMIT-XXXX-XXXX-XXXX-XXXX');
if ($result->isValid) {
echo 'Valid! Product: ' . $result->productName . PHP_EOL;
if ($result->hasFeature('export')) {
enableExport();
}
} else {
exit('License invalid: ' . $result->message);
}
Activate (call once per installation)
$result = $client->activate(
licenseKey: 'PERMIT-XXXX-XXXX-XXXX-XXXX',
deviceId: null, // auto-generated HWID
deviceName: 'Production Server'
);
if (!$result->isValid) {
exit('Activation failed: ' . $result->message);
}
// Save $result->isValid to local storage — use validate() on every subsequent launch.
Metered billing
// Record a single event
$client->meter('PERMIT-XXXX-XXXX-XXXX-XXXX', 'api_call');
// Record bulk usage with metadata
$client->meter(
licenseKey: 'PERMIT-XXXX-XXXX-XXXX-XXXX',
eventName: 'export',
quantity: 5,
meta: ['format' => 'pdf', 'pages' => 12]
);
Floating licenses
// Check out a seat at session start
$session = $client->checkout('PERMIT-XXXX-XXXX-XXXX-XXXX');
if (!$session->success) {
exit('No seats available: ' . $session->message);
}
$token = $session->sessionToken;
// Heartbeat every 4–5 minutes (use a cron job or event loop)
$client->heartbeat($token);
// Release when the user logs out or the session ends
$client->checkin($token);
Offline grace period
$result = $client->validate($licenseKey); // falls back to disk cache automatically
if ($result->isOffline) {
// Running on cached result — server unreachable
showNotice('Running offline. Connect to refresh your license.');
}
LicenseResult properties
| Property | 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 | ?array | 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 | ?string | Minimum app version the license allows |
maxVersion | ?string | Maximum app version the license allows |
vendorWarning | ?string | Non-fatal message from the vendor |
message | ?string | Reason when isValid = false |
isOffline | bool | True when result came from local cache |
hasFeature(string $feature): bool — case-insensitive check whether a feature flag is present on the license.