ExisOne API
All requests must include your access token:
Authorization: ExisOneApi <access-token>
All API endpoints enforce tokens (no request is processed without a valid token).
Public Key
GET /api/crypto/keys/public
Returns the current RSA public key in PEM format.
Activation
POST /api/license/activate
{
"activationKey": "AAAA-BBBB-CCCC-DDDD",
"email": "user@example.com",
"hardwareId": "HW-123",
"productName": "MyProduct"
}
Generate Activation Key
POST /api/activationkey/generate
{
"productName": "MyProduct",
"email": "user@example.com",
"planId": 1,
"validityDays": 365
}
- Send either
planIdorvalidityDays. If both are sent, planId overrides. - If neither is sent, the server uses the product's default license plan. Default of 0 means Perpetual (expires 2049-12-31).
Plans
GET /api/plan
POST /api/plan
{
"id": null,
"name": "365 days",
"durationDays": 365,
"isActive": true
}
Validation
Two modes are supported:
- Licensed validation (activation key present):
POST /api/license/validate
{
"activationKey": "AAAA-BBBB-CCCC-DDDD",
"hardwareId": "HW-123",
"productName": "MyProduct",
"version": "1.0"
}
Returns { isValid: true|false, status: "licensed"|"invalid", expirationDate, features: [], serverVersion?, minimumRequiredVersion? }.
Note (v0.6.0): expirationDate is now always returned, even for invalid licenses. For invalid cases, it's calculated from the device record creation date + trial days.
- Trial validation (activation key blank):
POST /api/license/validate
{
"activationKey": "",
"hardwareId": "HW-NEW",
"productName": "MyProduct",
"version": "1.0"
}
- If the device has never been activated for this product and the product has
TrialDays > 0, the server creates/updates a device record and returns{ isValid: true, status: "trial", expirationDate, remainingDays, features: [] }. - If the device was ever activated for this product, trial is not allowed and the server returns
{ isValid: false, status: "invalid", expirationDate }.
Device History
GET /api/license/device-history/{hardwareId}?page=1&pageSize=10
Returns paginated license history for a specific hardware ID in reverse chronological order.
Response: { items: [...], page: 1, pageSize: 10, totalCount: 100, totalPages: 10 }
Encrypted Payloads
Encrypt JSON with the public key (RSA-OAEP-SHA256), base64 encode, and send:
POST /api/license/validate-encrypted
{
"payload": "<base64 ciphertext>"
}
Response body is JSON; if encrypted variant is called, response will be base64 of RSA-encrypted JSON.