Skip to main content

License Verification API

Overview

The License Verification system validates whether a customer has active access to the photobooth. It supports two entitlement types: perpetual (one-time purchase) and recurring (subscription-based).

API Endpoints

Verify License Key

Endpoint: GET /v1/license/verify/:key

Verifies a license key and returns entitlement status.

Response:

{
valid: boolean;
licenseType: "starter" | "pro" | "enterprise";
activatedAt?: string; // ISO timestamp
expiresAt?: string; // For subscriptions
customerId?: string;
}

Code Reference: services/api/license/controller.ts - createLicenseController()


Get License by Customer

Endpoint: GET /v1/license/customer/:id

Retrieves license information for a specific customer.

Response:

{
customer: {
id: string;
name?: string;
email?: string;
phone?: string;
licenseType: "starter" | "pro" | "enterprise";
purchaseDate?: string;
} | null;
license: {
found: boolean;
key?: string;
isActive?: boolean;
activatedAt?: string;
updatedAt?: string;
};
}

Code Reference: services/api/license/controller.ts - GET /customer/:id


Entitlement Resolution

The resolve-active-entitlement use case determines if a customer has valid access:

  1. Check for active perpetual entitlement → always valid
  2. Check for active recurring entitlement → valid if within current period
  3. Return null if no valid entitlement found

Code Reference: services/api/entitlements/use-cases/resolve-active-entitlement.ts

License Types

TypeDescriptionEntitlement
starterBasic tierLimited features
proProfessional tierFull features
enterpriseEnterprise tierUnlimited + priority support

Verification Flow

  1. App Load: Frontend checks license via LicenseProvider
  2. Key Entry: Vendor enters license key
  3. API Call: GET /v1/license/verify/:key
  4. Response: Backend checks D1 database for entitlement
  5. Access Decision: Frontend unlocks features if valid

Code Reference

  • Controller: services/api/license/controller.ts
  • Service: services/api/license/service.ts
  • Use Cases: services/api/entitlements/use-cases/
  • Models: services/api/license/models.ts
  • Frontend Provider: apps/web/providers/license-provider.tsx

Database Schema (D1)

-- Licenses table
CREATE TABLE licenses (
id TEXT PRIMARY KEY,
customer_id TEXT NOT NULL,
key TEXT UNIQUE NOT NULL,
type TEXT NOT NULL, -- 'starter', 'pro', 'enterprise'
is_active INTEGER NOT NULL DEFAULT 1,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);

-- Entitlements table
CREATE TABLE entitlements (
id TEXT PRIMARY KEY,
customer_id TEXT NOT NULL,
type TEXT NOT NULL, -- 'perpetual', 'recurring'
status TEXT NOT NULL, -- 'active', 'revoked', 'expired'
granted_at TEXT NOT NULL,
expires_at TEXT, -- NULL for perpetual
revoked_at TEXT
);