Skip to content

Schemas

Sequence diagram — License activation & management

This assumes a publisher has already been provisioned by the platform operator (POST /platform/publishers) and has its own X-Client-Token / X-Admin-Token. "User" below is the publisher's end user, not a customer of this API directly — see Overview.

What happens step-by-step:
1. Activation – the end user launches the publisher's app and enters the license key. The app calls POST /activate (with the publisher's X-Client-Token) and email, license_key, device_hash, device_name. The API rate-limits per (publisher, email), checks ownership, enabled status, and device quota, then returns a signed token (with a kid) that the app stores to unlock Pro features.
2. (Optional) Verification – the app fetches the signing keys via GET /public-keys, picks the one matching the token's kid, and verifies the token signature (Ed25519) — entirely offline.
3. Admin management – a publisher admin can create/list licenses and enable/disable a license (immediate effect), scoped to their own publisher account.
4. Device change – when the end user moves to a new machine, the app calls POST /deactivate to free a slot and activate elsewhere.

%%{init: { "theme": "base", "sequence": { "showSequenceNumbers": true, "useMaxWidth": true }, "themeVariables": { "darkMode": true, "background": "transparent", "fontSize": "18px", "primaryTextColor": "#e7ebf2", "actorTextColor": "#e7ebf2", "noteTextColor": "#dfe4ec", "lineColor": "#8fb4ff", "signalColor": "#8fb4ff", "actorBorder": "#8fb4ff", "actorBkg": "#1b2330", "activationBorderColor":"#8fb4ff", "activationBkgColor": "#242e3d", "noteBkgColor": "#242e3d" } }}%% sequenceDiagram autonumber actor User as End user (publisher's customer) participant App as Publisher's app participant API as Licenses API participant Admin as Publisher's admin participant Key as Signing keys (GET /public-keys) User->>App: Launch app / enter license key App->>API: POST /activate\n{ email, license_key,\n device_hash, device_name }\n(X-Client-Token: this publisher's) API-->>API: Rate-limit check (publisher, email)\nValidate license (status, email owner, device quota) API-->>App: 200 { signed token + kid + metadata } Note over App: App stores the signed token\nand unlocks Pro features rect rgb(27,35,48) App->>Key: GET /public-keys (cache by kid) App-->>App: Verify token signature (Ed25519) end Admin->>API: Enable/Disable, list, create licenses\n(X-Admin-Token: this publisher's) API-->>Admin: License details + active devices User->>App: Moves to a new machine App->>API: POST /deactivate\n{ license_key_hash, device_hash } API-->>App: Slot freed (can activate elsewhere)

Entity–Relationship diagram

  • PUBLISHERS: one row per tenant (game studio, SaaS, software vendor) — holds the hashed client_token/admin_token and an enabled kill switch. Everything else is scoped to a publisher.
  • USERS: one row per (publisher, email) — the same email can exist independently under two different publishers.
  • LICENSES: belongs to a publisher and a user; stores license_key_hash, product, edition, enabled, max_activations, optional features_json, timestamps.
  • ACTIVATIONS: each record links a license to a device (device_hash, device_name), with deactivated flag and timestamp.
  • Supporting tables not shown below: SIGNING_KEYS (rotatable Ed25519 keys, platform-wide), RATE_LIMIT_HITS (per publisher+email throttling on /activate), AUDIT_LOG (append-only trail of admin/platform actions).

Relationships - A PUBLISHER has many USERS and many LICENSES. - A USER has many LICENSES. - A LICENSE has many ACTIVATIONS (devices).

erDiagram PUBLISHERS ||--o{ USERS : scopes PUBLISHERS ||--o{ LICENSES : scopes USERS ||--o{ LICENSES : owns LICENSES ||--o{ ACTIVATIONS : has