Skip to main content

Overview

The activate endpoint activates a license key on the current machine, binding it permanently to that specific machine. Once activated, the license can only be validated on the same machine.

Endpoint

POST /validate/activate
This endpoint is rate-limited to 5 requests per IP address within a 15-minute window.

Request

Request Body

key
string
required
The license key to activate

Example Request

curl -X POST https://your-keybox-server.com/validate/activate \
  -H "Content-Type: application/json" \
  -d '{
    "key": "KB-PROJ123-XXXX-XXXX-XXXX"
  }'

Response

Success Response

success
boolean
Whether the activation was successful
message
string
Description of the activation result
machineId
string
The hashed machine ID the license is now bound to
activatedAt
date
ISO timestamp of when the license was activated
expiresAt
date
ISO timestamp of when the license will expire

Example Response - First Activation

{
  "success": true,
  "message": "License activated successfully",
  "machineId": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
  "activatedAt": "2024-01-01T00:00:00.000Z",
  "expiresAt": "2025-01-01T00:00:00.000Z"
}

Example Response - Already Activated (Same Machine)

{
  "success": true,
  "message": "License already activated on this machine",
  "activatedAt": "2024-01-01T00:00:00.000Z",
  "expiresAt": "2025-01-01T00:00:00.000Z"
}

Activation Process

1

Generate Machine ID

The server generates a unique, hashed machine ID based on hardware characteristics
2

Check License Status

The license status is verified (must be PENDING or ACTIVE)
3

Bind to Machine

For first-time activation, the license is bound to the current machine ID
4

Set Expiration

The expiration date is calculated based on the license duration
5

Update Status

License status is changed from PENDING to ACTIVE
6

Invalidate Cache

Redis cache is invalidated to ensure fresh validation results

License Duration

When a license is activated for the first time:
  • Issued At: Set to the current date/time
  • Expires At: Calculated as issuedAt + duration months
  • Duration: Between 1-12 months (configured when license is created)
The expiration period only begins when the license is first activated, not when it’s created.

Error Responses

Missing License Key

Status Code: 400
{
  "success": false,
  "message": "License key is required"
}

License Not Found

Status Code: 404
{
  "success": false,
  "message": "License not found"
}

License Revoked

Status Code: 403
{
  "success": false,
  "message": "License has been revoked"
}

License Expired

Status Code: 403
{
  "success": false,
  "message": "License has expired"
}

Already Activated on Different Machine

Status Code: 403
{
  "success": false,
  "message": "License already activated on another machine"
}

Rate Limit Exceeded

Status Code: 429
{
  "success": false,
  "errors": "too many requests, please try again later.",
  "status": 429
}

Server Error

Status Code: 500
{
  "success": false,
  "message": "Activation failed",
  "error": "Detailed error message"
}

Machine Binding Behavior

When a license is activated:
  1. Machine ID Generation: A unique ID is generated based on hardware characteristics (CPU, motherboard, etc.) and then hashed for security
  2. First Activation: The machine ID is stored with the license
  3. Subsequent Checks: All validation requests verify the machine ID matches
  4. Security: The hashed ID prevents reverse-engineering while ensuring uniqueness
If you try to activate or validate a license on a different machine:
  • Activation: Returns 403 error - “License already activated on another machine”
  • Validation: Returns machine_mismatch status
  • Bypass: The only way to use the license on a new machine is to revoke and recreate it
The machine ID is based on stable hardware characteristics:
  • Should remain consistent across reboots
  • Should remain consistent across OS updates
  • May change if hardware components are replaced
  • Uses cryptographic hashing for security

Integration Example

class LicenseActivator {
  constructor(serverUrl, licenseKey) {
    this.serverUrl = serverUrl;
    this.licenseKey = licenseKey;
  }

  async activate() {
    try {
      const response = await fetch(`${this.serverUrl}/validate/activate`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ key: this.licenseKey })
      });

      const data = await response.json();

      if (data.success) {
        console.log('License activated successfully');
        console.log('Expires at:', new Date(data.expiresAt));
        return true;
      } else {
        console.error(`Activation failed: ${data.message}`);
        return false;
      }
    } catch (error) {
      console.error('Activation request failed:', error);
      return false;
    }
  }
}

// Usage
const activator = new LicenseActivator(
  'https://your-keybox-server.com',
  'KB-PROJ123-XXXX-XXXX-XXXX'
);

const activated = await activator.activate();
if (!activated) {
  console.error('Please check your license key and try again');
}

Best Practices

First-Run Only

Only call activation once during initial setup or installation

Store Locally

Cache activation status to avoid repeated API calls

User Feedback

Provide clear feedback about activation success or failure

Handle Errors

Gracefully handle all error scenarios with helpful messages

See Also

Build docs developers (and LLMs) love