openapi: 3.1.0 info: title: Universal License Platform API version: 1.0.0 description: Management and runtime validation API for signed product licenses. servers: - url: https://licenses.example.org paths: /.well-known/license-server: get: summary: Discover the license platform responses: '200': description: Discovery document content: application/json: schema: $ref: '#/components/schemas/Discovery' /api/v1/trust-store: get: summary: Read public issuer and lease verification keys responses: '200': description: Public Ed25519 trust store content: application/json: schema: $ref: '#/components/schemas/TrustStore' '503': $ref: '#/components/responses/Error' /api/v1/licenses/validate: post: summary: Validate a license and issue a short-lived signed lease requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ValidationRequest' responses: '200': description: Valid license and signed lease content: application/json: schema: $ref: '#/components/schemas/ValidationResponse' '400': $ref: '#/components/responses/Error' '403': $ref: '#/components/responses/Error' '429': $ref: '#/components/responses/Error' /api/v1/licenses: get: security: [{bearerAuth: []}] summary: List licenses visible to the management actor responses: '200': description: License list without plaintext tokens content: application/json: schema: type: object required: [licenses] properties: licenses: type: array items: {$ref: '#/components/schemas/License'} '401': {$ref: '#/components/responses/Error'} post: security: [{bearerAuth: []}] summary: Sign and register a license requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/IssueLicense' responses: '201': description: Created license; plaintext token is returned only here content: application/json: schema: $ref: '#/components/schemas/License' '400': {$ref: '#/components/responses/Error'} '401': {$ref: '#/components/responses/Error'} /api/v1/licenses/import: post: security: [{bearerAuth: []}] summary: Register an already signed, still-valid license token requestBody: required: true content: application/json: schema: type: object additionalProperties: false required: [token] properties: token: {type: string, minLength: 20} customerUserId: {type: string} responses: '201': description: Imported license content: application/json: schema: {$ref: '#/components/schemas/License'} '400': {$ref: '#/components/responses/Error'} '401': {$ref: '#/components/responses/Error'} /api/v1/licenses/{licenseId}/revoke: post: security: [{bearerAuth: []}] summary: Revoke a registered license parameters: - $ref: '#/components/parameters/LicenseId' requestBody: required: false content: application/json: schema: type: object properties: reason: {type: string, maxLength: 500} responses: '200': {$ref: '#/components/responses/Mutation'} '401': {$ref: '#/components/responses/Error'} '404': {$ref: '#/components/responses/Error'} /api/v1/licenses/{licenseId}/restore: post: security: [{bearerAuth: []}] summary: Restore a revoked license parameters: - $ref: '#/components/parameters/LicenseId' responses: '200': {$ref: '#/components/responses/Mutation'} '401': {$ref: '#/components/responses/Error'} '404': {$ref: '#/components/responses/Error'} components: securitySchemes: bearerAuth: type: http scheme: bearer parameters: LicenseId: name: licenseId in: path required: true schema: {type: string} responses: Error: description: Error response content: application/json: schema: type: object properties: error: {type: string} reason: {type: string} Mutation: description: License status changed content: application/json: schema: type: object required: [licenseId, revoked] properties: licenseId: {type: string} revoked: {type: boolean} schemas: Discovery: type: object required: [issuer, serverUrl, validationEndpoint, trustStoreEndpoint] properties: issuer: {type: string} serverUrl: {type: string, format: uri} validationEndpoint: {type: string, format: uri} trustStoreEndpoint: {type: string, format: uri} TrustStore: type: object required: [licenseKeys, leaseKeys] properties: licenseKeys: type: object additionalProperties: {type: string} leaseKeys: type: object additionalProperties: {type: string} ValidationRequest: type: object additionalProperties: false required: [token, product, baseUrl] properties: token: {type: string, minLength: 20} product: {type: string, minLength: 1} baseUrl: {type: string, format: uri} host: {type: string} instanceId: {type: string} clientVersion: {type: string} ValidationResponse: type: object required: [valid] properties: valid: {type: boolean} leaseToken: {type: string} expiresAt: {type: string, format: date-time} reason: {type: string} IssueLicense: type: object additionalProperties: false required: [customer, product, edition, mode, days] properties: customerUserId: {type: string} customer: {type: string, minLength: 1} product: {type: string, minLength: 1} edition: {type: string, minLength: 1} features: type: array items: {type: string} uniqueItems: true limits: type: object additionalProperties: {type: integer, minimum: 0} domains: type: array items: {type: string} uniqueItems: true instanceIds: type: array items: {type: string} uniqueItems: true mode: {enum: [offline, hybrid, online]} days: {type: integer, minimum: 1, maximum: 3650} leaseMinutes: {type: integer, minimum: 1, maximum: 1440, default: 60} graceHours: {type: integer, minimum: 0, maximum: 8760, default: 72} License: allOf: - $ref: '#/components/schemas/IssueLicense' - type: object required: [licenseId, issuer, serverUrl, expiresAt, revoked, createdAt, updatedAt] properties: licenseId: {type: string} issuer: {type: string} serverUrl: {type: string, format: uri} expiresAt: {type: integer} revoked: {type: boolean} reason: {type: string} token: type: string description: Present only in create and explicitly authorized token-delivery responses. createdAt: {type: integer} updatedAt: {type: integer}