Every software product that sells licenses needs an API. Whether you're building a desktop app, a CLI tool, or a SaaS platform with on-premise deployments, you need a way to generate, validate, and manage license keys programmatically. In this guide, we'll walk through building a complete license key API from scratch.
Why Build a License Key API?
A license key API gives you programmatic control over your entire licensing workflow. Instead of manually issuing keys through a dashboard, your systems can:
- Auto-generate keys when a customer completes checkout
- Validate keys from your app at runtime in under 50ms
- Revoke or suspend keys when subscriptions lapse
- Track usage across domains, devices, and geographies
- Send webhooks when license events occur
Designing the API Schema
A well-designed license key API needs these core endpoints:
POST /api/v1/licenses # Create a new license
GET /api/v1/licenses/:id # Get license details
POST /api/v1/validate # Validate a key at runtime
PUT /api/v1/licenses/:id # Update license (plan, limits)
DELETE /api/v1/licenses/:id # Revoke a license
GET /api/v1/licenses/:id/usage # Get validation history
The License Object
Every license should contain these core fields:
{
"id": "lic_a1b2c3d4e5",
"key": "TO-XXXX-XXXX-XXXX-XXXX",
"status": "active", // active | suspended | expired | revoked
"plan": "professional",
"customer_email": "dev@example.com",
"max_domains": 3,
"domains": ["example.com", "staging.example.com"],
"created_at": "2026-03-06T00:00:00Z",
"expires_at": "2027-03-06T00:00:00Z",
"last_validated_at": "2026-03-06T12:34:56Z",
"validation_count": 1247
}
Key Generation: Getting It Right
License key format matters more than you think. Keys need to be:
- Unique — No collisions, even at scale
- Unpredictable — Can't be guessed or enumerated
- Human-readable — Easy to type and support
- Checksummable — Detect typos before hitting the server
// Generate a cryptographically secure license key
import crypto from 'crypto';
function generateLicenseKey(prefix = 'TO'): string {
const bytes = crypto.randomBytes(16);
const hex = bytes.toString('hex').toUpperCase();
const segments = hex.match(/.{4}/g)!;
return prefix + '-' + segments.join('-');
}
// Result: TO-A3F2-B891-C4D7-E052
The Validation Endpoint
The validation endpoint is the most critical part of your API. It's called on every app launch, potentially millions of times per day. It needs to be fast, reliable, and secure.
// POST /api/v1/validate
app.post('/api/v1/validate', async (c) => {
const { key, domain, fingerprint } = await c.req.json();
// 1. Find the license
const license = await db.query(
'SELECT * FROM licenses WHERE key = ?', [key]
);
if (!license) {
return c.json({ valid: false, error: 'LICENSE_NOT_FOUND' }, 404);
}
// 2. Check status and expiry
if (license.status !== 'active') {
return c.json({ valid: false, error: 'LICENSE_' + license.status.toUpperCase() });
}
if (new Date(license.expires_at) < new Date()) {
return c.json({ valid: false, error: 'LICENSE_EXPIRED' });
}
// 3. Domain validation
if (domain && !license.domains.includes(domain)) {
if (license.domains.length >= license.max_domains) {
return c.json({ valid: false, error: 'DOMAIN_LIMIT_REACHED' });
}
}
// 4. Record the validation
await db.run('UPDATE licenses SET last_validated_at = ?, validation_count = validation_count + 1 WHERE id = ?',
[new Date().toISOString(), license.id]);
return c.json({
valid: true,
license: {
plan: license.plan,
expiresAt: license.expires_at,
features: getPlanFeatures(license.plan)
}
});
});
Performance: Sub-50ms Validation
Your validation endpoint will be called on every app launch. Users don't want to wait. Here's how to achieve sub-50ms response times:
- Edge deployment — Run validation logic on CDN edge nodes (edge runtimes, serverless functions)
- Caching — Cache active licenses in KV storage with 5-minute TTL
- Prepared statements — Pre-compile SQL queries
- Connection pooling — Reuse database connections
Traffic Orchestrator validates licenses in under 35ms at the 95th percentile, deployed across 300+ edge locations worldwide.
Webhooks: Real-Time License Events
Webhooks let your systems react to license events in real time. Essential events to support:
license.created— New license issuedlicense.activated— First successful validationlicense.expired— License reached expiry datelicense.suspended— Payment failedlicense.revoked— Manually revoked by admin
Or Just Use Traffic Orchestrator
Building a license key API from scratch takes weeks of engineering time. Or you can be up and running in 5 minutes with Traffic Orchestrator. We handle key generation, validation, webhooks, SDKs for 12 languages, a customer portal, and edge-deployed infrastructure — so you can focus on your product.
Ship licensing in your next release
5 licenses, 500 validations/month, full API access. Set up in under 5 minutes — no credit card required.