New desktop/public integrations should use the Secure API v2 endpoints documented in API_V2.md. API v2 does not use the shared API v1 X-API-Key credential. Existing API v1 integrations remain supported and unchanged.
POST /api/verify.php
Content-Type: application/jsonX-API-Key: <key>— API v1 credential for trusted/legacy integrations.
API v1 accepts its reviewed API-key credential paths for backward compatibility. This credential model is intentionally not used by API v2 desktop/public clients.
{
"license_key": "AAAAAAAA-BBBBBBBB-CCCCCCCC-DDDDDDDD",
"device_hash": "client-generated-stable-identifier",
"app_id": "desktop-client",
"app_version": "1.0.0"
}license_key is required and must use four groups of eight uppercase alphanumeric characters. device_hash, app_id, and app_version are optional. A missing device hash is generated from request headers on the server, which is less reliable than a stable client-generated value.
{
"success": true,
"license": {
"key": "AAAAAAAA-BBBBBBBB-CCCCCCCC-DDDDDDDD",
"expires": "2026-12-31 23:59:59",
"device_limit": 1,
"devices_used": 1,
"status": "active",
"created_at": "2026-07-22 12:00:00"
},
"device_hash": "client-generated-stable-identifier",
"timestamp": "2026-07-22T12:00:00+06:00",
"server_time": 1784700000,
"server_version": "2.0",
"message": "License valid"
}Possible failures include missing/invalid API key, malformed JSON, invalid request fields, invalid or expired license, suspended/blacklisted access, API-key or application-scope mismatch, device-limit exhaustion, and rate limiting.
- A license with
api_key_idaccepts only that API key. - A license with
app_scopebut no direct key binding compares the license scope with the API key'sapp_nameorscope_label. - Unscoped licenses retain legacy behavior.
POST /api/check_license.php
{
"license_key": "AAAAAAAA-BBBBBBBB-CCCCCCCC-DDDDDDDD",
"device_hash": "client-generated-stable-identifier"
}This endpoint does not require an API key and calls license verification without an API-key context. It is retained for backward compatibility but should not be exposed to untrusted networks without an external gateway rule. Scoped licenses may fail because no API-key context is supplied.
Both endpoints use an IP-and-endpoint counter in rate_limits with a one-hour window. The full endpoint applies the global API_RATE_LIMIT; the per-key rate_limit_per_hour column is currently not enforced.
The full endpoint returns Access-Control-Allow-Origin only when the request origin exactly matches LICENSE_ALLOWED_ORIGIN or APP_URL. The simple endpoint does not implement CORS headers.
The full endpoint explicitly uses 200, 400, 401, 405, and 429 in key paths. Some license failures are serialized with a response body while the final HTTP status may remain 200; integrations must inspect the success field.