KeyPort LogoKeyPort
Back to all guides
Tutorial• April 2026

How to Add License Key Validation to Your Software in 10 Minutes

Stop building from scratch. Use a REST API to validate license keys in any language — JavaScript, PHP, Python. Ships in under 10 minutes.

DP
Darshak ParmarAuthor • 5 min read

Every developer building paid software hits the same wall: how do I actually enforce who can use my app?

You could build a license key system from scratch — database, key generation, validation logic, expiry handling, IP tracking. That's weeks of work on infrastructure that's not your product. Or you can use a validation API and ship in 10 minutes.

This guide uses KeyPort. The approach works for any language.

Why License Validation Matters

Without enforcement, anyone who copies your software binary can use it. Even well-meaning users share keys. License validation closes that gap: your app checks in with the API on startup, the API confirms whether the key is valid, and your app acts accordingly.

The validation happens server-side, so there's nothing to crack locally.

Step 1 — Create Your Product on KeyPort

Sign up at app.keyport.sbs (free, no credit card). Create an organization, then create a product. You'll get a product API key — keep it server-side, never expose it in client code.

# Your product API key (keep secret, server-side only)
KEYPORT_API_KEY=kp_live_xxxxxxxxxxxxxxxxxxxx

Step 2 — Issue a License Key to a Customer

From the KeyPort dashboard, navigate to your product and click New license. Enter the customer email and set an expiry date if required. You'll get a license key in the format XXXX-XXXX-XXXX-XXXX. Give this to your customer at checkout.

Step 3 — Validate From Your Application

On every app startup (or periodically), make a POST request to the validate endpoint.

JavaScript / Node.js

const res = await fetch('https://api.keyport.sbs/api/v1/validate', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${process.env.KEYPORT_API_KEY}`
  },
  body: JSON.stringify({ license_key: 'ABCD-EFGH-IJKL-MNOP' })
});

const data = await res.json();

if (data.valid) {
  console.log('License valid. Status:', data.status);
} else {
  console.log('License invalid. Reason:', data.status);
  // data.status: expired | revoked | ip_blocked | not_found
}

PHP

function validateLicense(string $key): array {
    $ch = curl_init('https://api.keyport.sbs/api/v1/validate');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $_ENV['KEYPORT_API_KEY']
        ],
        CURLOPT_POSTFIELDS => json_encode(['license_key' => $key])
    ]);
    return json_decode(curl_exec($ch), true);
}

$result = validateLicense('ABCD-EFGH-IJKL-MNOP');
if ($result['valid']) { /* start app */ }
else { die('Invalid license: ' . $result['status']); }

Python

import requests, os

def validate_license(key: str) -> dict:
    return requests.post(
        'https://api.keyport.sbs/api/v1/validate',
        headers={
            'Authorization': f"Bearer {os.environ['KEYPORT_API_KEY']}",
            'Content-Type': 'application/json'
        },
        json={'license_key': key}
    ).json()

result = validate_license('ABCD-EFGH-IJKL-MNOP')
if not result['valid']:
    print(f"Blocked. Reason: {result['status']}")
    exit(1)

Status Codes to Handle

StatusMeaningRecommended action
activeLicense is validAllow full access
expiredPast expiry dateShow renewal prompt
revokedManually disabledShow contact support
ip_blockedIP is blockedShow contact support
not_foundKey doesn't existShow invalid key error

Next Steps

  • Enable IP tracking to limit machines per key
  • Add webhooks to get notified on events
  • Share the customer portal link so users can view their own keys

Scale your product with KeyPort

Free tier available for launch and small production workloads. No credit card required.