Integration Guide
This guide shows how to integrate ValidonX license validation and activation into your application using PHP and JavaScript.
PHP Integration
License Validation
php
<?php
class ValidonX
{
private string $apiKey;
private string $baseUrl;
public function __construct(string $apiKey, string $baseUrl = 'https://api.validonx.com/api')
{
$this->apiKey = $apiKey;
$this->baseUrl = $baseUrl;
}
public function validateLicense(string $licenseKey): array
{
$ch = curl_init("{$this->baseUrl}/v1/integration/licenses/{$licenseKey}/validate");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-API-Key: {$this->apiKey}",
'Content-Type: application/json',
],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($response, true);
if ($status !== 200) {
throw new \Exception($data['error']['message'] ?? 'License validation failed');
}
return $data['data'];
}
// $instanceId (required): a stable, unique per-install seat identity.
// $deviceFingerprint (optional, recommended): a hash of hardware identifiers
// recorded with the activation. instance_id is client-chosen, so a
// hardware-derived fingerprint gives each seat an auditable device identity.
public function createActivation(string $licenseKey, string $instanceId, ?string $deviceFingerprint = null, array $metadata = []): array
{
$payload = [
'license_key' => $licenseKey,
'instance_id' => $instanceId,
'metadata' => $metadata,
];
if ($deviceFingerprint !== null) {
$payload['device_fingerprint'] = $deviceFingerprint;
}
$ch = curl_init("{$this->baseUrl}/v1/integration/activations");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-API-Key: {$this->apiKey}",
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($response, true);
if ($status !== 201 && $status !== 200) {
throw new \Exception($data['error']['message'] ?? 'Activation failed');
}
return $data['data'];
}
public function checkEntitlements(array $codes): array
{
$ch = curl_init("{$this->baseUrl}/v1/integration/entitlements/check");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-API-Key: {$this->apiKey}",
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['entitlement_codes' => $codes]),
]);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true)['data'] ?? [];
}
}
// Usage
$vx = new ValidonX('vx_your-api-key');
// Validate license
$result = $vx->validateLicense('XXXX-XXXX-XXXX-XXXX');
if ($result['valid']) {
echo "License is valid!\n";
echo "Plan: " . ($result['license']['entitlements']['plan'] ?? 'none') . "\n";
}
// Activate on this device
$activation = $vx->createActivation(
'XXXX-XXXX-XXXX-XXXX',
// required: a stable, unguessable instance id — generate once per install
// (e.g. a random UUID) and persist it; don't reuse a shared/guessable value.
'3f9c2e1a-7b4d-4c8a-9e2f-6d1b0a5e8c74',
hash('sha256', php_uname()), // optional but recommended: device fingerprint
['app_version' => '2.0.0']
);
echo "Activation ID: " . $activation['activation']['id'] . "\n";JavaScript / Node.js Integration
javascript
class ValidonX {
constructor(apiKey, baseUrl = 'https://api.validonx.com/api') {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
}
async validateLicense(licenseKey) {
const res = await fetch(
`${this.baseUrl}/v1/integration/licenses/${licenseKey}/validate`,
{
method: 'POST',
headers: {
'X-API-Key': this.apiKey,
'Content-Type': 'application/json',
},
}
);
const json = await res.json();
if (!res.ok) throw new Error(json.error?.message || 'Validation failed');
return json.data;
}
// instanceId (required): stable, unique per-install seat identity.
// deviceFingerprint (optional, recommended): hash of hardware identifiers
// recorded with the activation. instance_id is client-chosen, so a
// hardware-derived fingerprint gives each seat an auditable device identity.
async createActivation(licenseKey, instanceId, deviceFingerprint = null, metadata = {}) {
const body = { license_key: licenseKey, instance_id: instanceId, metadata };
if (deviceFingerprint) body.device_fingerprint = deviceFingerprint;
const res = await fetch(`${this.baseUrl}/v1/integration/activations`, {
method: 'POST',
headers: {
'X-API-Key': this.apiKey,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
const json = await res.json();
if (!res.ok) throw new Error(json.error?.message || 'Activation failed');
return json.data;
}
async checkEntitlements(codes) {
const res = await fetch(
`${this.baseUrl}/v1/integration/entitlements/check`,
{
method: 'POST',
headers: {
'X-API-Key': this.apiKey,
'Content-Type': 'application/json',
},
body: JSON.stringify({ entitlement_codes: codes }),
}
);
const json = await res.json();
return json.data;
}
}
// Usage
const vx = new ValidonX('vx_your-api-key');
const result = await vx.validateLicense('XXXX-XXXX-XXXX-XXXX');
console.log('Valid:', result.valid);
console.log('Plan:', result.license?.entitlements?.plan);
const activation = await vx.createActivation(
'XXXX-XXXX-XXXX-XXXX',
// required: stable, unguessable instance id generated once per install
// (e.g. crypto.randomUUID()) and persisted — not a shared/guessable value.
'3f9c2e1a-7b4d-4c8a-9e2f-6d1b0a5e8c74',
'sha256-of-hardware-ids', // optional but recommended: device fingerprint
{ app_version: '2.0.0', os: 'Linux' }
);
console.log('Activation ID:', activation.activation.id);Error Handling
All errors follow the standard envelope format. Always check for error responses:
javascript
try {
const result = await vx.validateLicense(key);
} catch (error) {
// error.message contains the human-readable error
// Common codes: LICENSE.NOT_FOUND, LICENSE.REVOKED, RATE_LIMIT.EXCEEDED
}Rate Limiting
Check response headers to monitor your rate limit status:
javascript
const res = await fetch(url, options);
const remaining = res.headers.get('X-RateLimit-Remaining');
const limit = res.headers.get('X-RateLimit-Limit');
console.log(`${remaining}/${limit} requests remaining`);If you receive a 429 response, wait for the Retry-After seconds before retrying.