Skip to main content

Overview

The validate endpoint checks if a license key is valid and can be used on the current machine. This endpoint uses Redis caching for performance and implements machine binding to prevent license sharing.

Endpoint

POST /validate
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 validate

Example Request

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

Response

Success - Active License

valid
boolean
Whether the license is valid and active
status
string
License status: "active", "pending", "expired", "revoked", "invalid", or "machine_mismatch"
duration
string
License duration (e.g., β€œ12 months”)
expiresAt
number
Expiration timestamp in milliseconds

Example Response - Active

{
  "valid": true,
  "status": "active",
  "duration": "12 months",
  "expiresAt": 1704067200000
}

Example Response - Invalid Key

{
  "valid": false,
  "status": "invalid",
  "message": "Key does not exist"
}

Example Response - Machine Mismatch

{
  "valid": false,
  "status": "machine_mismatch",
  "message": "License is not valid for this machine"
}

Example Response - Expired

{
  "valid": false,
  "status": "expired",
  "message": "License has expired",
  "expiresAt": 1704067200000
}

Example Response - Pending Activation

{
  "valid": false,
  "status": "pending",
  "message": "License has not been activated yet"
}

Example Response - Revoked

{
  "valid": false,
  "status": "revoked",
  "message": "License revoked by developer"
}

License Status Values

active
status
License is active and valid for use on the current machine
pending
status
License exists but has not been activated yet
expired
status
License duration has elapsed and is no longer valid
revoked
status
License has been manually revoked by the developer
invalid
status
License key does not exist in the database
machine_mismatch
status
License is active but bound to a different machine

Machine Binding

Licenses are bound to the machine they are first activated on. The system uses a hashed machine ID for verification.
When a license is activated:
  1. The server generates a unique, hashed machine ID
  2. This ID is stored with the license
  3. Future validation requests check if the machine ID matches
  4. If the machine ID differs, validation fails with machine_mismatch status
This prevents license keys from being shared across multiple machines.

Caching Strategy

The validation endpoint uses Redis caching to minimize database queries and improve performance.

Cache Flow

  1. Cache Hit: If license is in Redis, return cached status immediately
  2. Cache Miss: Query MongoDB, then cache the result
  3. Cache Invalidation: Cache is invalidated when license status changes

Performance Benefits

  • Faster validation for frequently checked licenses
  • Reduced database load
  • Better scalability for high-volume applications

Error Responses

Missing License Key

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

Rate Limit Exceeded

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

Server Error

Status Code: 500
{
  "valid": null,
  "status": "server_error",
  "message": "Internal validation error",
  "error": "Detailed error message"
}

Integration Example

Here’s a complete example of integrating license validation into your application:
class LicenseValidator {
  constructor(serverUrl, licenseKey) {
    this.serverUrl = serverUrl;
    this.licenseKey = licenseKey;
  }

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

      const data = await response.json();

      if (data.valid) {
        console.log('License is valid');
        return true;
      } else {
        console.error(`License validation failed: ${data.message}`);
        return false;
      }
    } catch (error) {
      console.error('Validation request failed:', error);
      return false;
    }
  }
}

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

const isValid = await validator.validate();
if (!isValid) {
  // Handle invalid license
  process.exit(1);
}

Best Practices

Cache Results

Cache validation results locally to minimize API calls

Handle Errors

Gracefully handle all possible status values

Retry Logic

Implement retry logic for transient failures

Offline Mode

Consider offline validation for extended network outages

See Also

Build docs developers (and LLMs) love