openapi: 3.1.0
info:
  title: VIX Licensing API
  version: 1.1.0
  description: API v1 para activación, validación y gestión de estado de licencias de productos VIX Hosting.
  contact:
    name: VIX Hosting
    url: https://www.vix.pe
    email: soporte@vix.pe
servers:
  - url: /api/v1
paths:
  /health:
    get:
      operationId: health
      responses:
        '200': {description: Servicio disponible}
  /keys:
    get:
      operationId: publicKeys
      responses:
        '200': {description: Keyset público Ed25519}
  /licenses/activate:
    post:
      operationId: activateLicense
      security: [{PublicClient: []}, {HmacClient: []}]
      parameters:
        - $ref: '#/components/parameters/ClientId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema: {$ref: '#/components/schemas/ActivationRequest'}
      responses:
        '201': {$ref: '#/components/responses/LicenseSuccess'}
        '409': {$ref: '#/components/responses/ApiError'}
        '422': {$ref: '#/components/responses/ApiError'}
  /licenses/validate:
    post:
      operationId: validateLicense
      security: [{PublicClient: []}, {HmacClient: []}]
      parameters:
        - $ref: '#/components/parameters/ClientId'
      requestBody:
        required: true
        content:
          application/json:
            schema: {$ref: '#/components/schemas/ValidationRequest'}
      responses:
        '200': {$ref: '#/components/responses/LicenseSuccess'}
        '403': {$ref: '#/components/responses/ApiError'}
  /licenses/deactivate:
    post:
      operationId: deactivateLicense
      security: [{PublicClient: []}, {HmacClient: []}]
      parameters:
        - $ref: '#/components/parameters/ClientId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema: {$ref: '#/components/schemas/ValidationRequest'}
      responses:
        '200': {description: Activación desactivada}
  /licenses/status:
    post:
      operationId: licenseStatus
      security: [{PublicClient: []}, {HmacClient: []}]
      parameters:
        - $ref: '#/components/parameters/ClientId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [license_key, product]
              properties:
                license_key: {type: string}
                product: {type: string}
      responses:
        '200': {description: Estado actual de licencia}
  /updates/check:
    post:
      operationId: checkWordPressUpdate
      security: [{PublicClient: []}, {HmacClient: []}]
      parameters:
        - $ref: '#/components/parameters/ClientId'
      requestBody:
        required: true
        content:
          application/json:
            schema: {$ref: '#/components/schemas/WordPressUpdateCheckRequest'}
      responses:
        '200': {description: Metadata de actualización WordPress}
        '403': {$ref: '#/components/responses/ApiError'}
  /updates/packages/{ticket}:
    post:
      operationId: downloadWordPressUpdatePackage
      security: [{PublicClient: []}, {HmacClient: []}]
      parameters:
        - $ref: '#/components/parameters/ClientId'
        - name: ticket
          in: path
          required: true
          schema: {type: string}
      requestBody:
        required: true
        content:
          application/json:
            schema: {$ref: '#/components/schemas/WordPressPackageRequest'}
      responses:
        '200':
          description: ZIP privado autorizado
          content:
            application/zip: {}
        '410': {$ref: '#/components/responses/ApiError'}
components:
  securitySchemes:
    PublicClient:
      type: apiKey
      in: header
      name: X-VIX-Client-ID
    HmacClient:
      type: apiKey
      in: header
      name: X-VIX-Signature
      description: Firma v1 HMAC-SHA256. Requiere además X-VIX-Client-ID, X-VIX-Timestamp y X-VIX-Nonce.
  parameters:
    ClientId:
      name: X-VIX-Client-ID
      in: header
      required: true
      schema: {type: string}
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: true
      schema: {type: string, minLength: 8, maxLength: 120}
  schemas:
    WordPressUpdateCheckRequest:
      type: object
      required: [license_key, product, installation_id, site_url, current_version, channel, package_type, package_slug, php_version, cms_version]
      properties:
        license_key: {type: string}
        product: {type: string}
        installation_id: {type: string}
        site_url: {type: string, format: uri}
        current_version: {type: string}
        channel: {type: string, enum: [stable, beta, developer]}
        package_type: {type: string, enum: [plugin, theme]}
        package_slug: {type: string}
        php_version: {type: string}
        cms_version: {type: string}
        locale: {type: string}
    WordPressPackageRequest:
      type: object
      required: [license_key, product, installation_id, site_url]
      properties:
        license_key: {type: string}
        product: {type: string}
        installation_id: {type: string}
        site_url: {type: string, format: uri}
    ActivationRequest:
      type: object
      required: [license_key, product, installation_id, site_url]
      properties:
        license_key: {type: string}
        product: {type: string}
        installation_id: {type: string, minLength: 8, maxLength: 255}
        site_url: {type: string}
        installation_label: {type: string, maxLength: 160}
        platform: {type: string, maxLength: 50}
        product_version: {type: string, maxLength: 40}
        php_version: {type: string, maxLength: 30}
        cms_version: {type: string, maxLength: 40}
        metadata: {type: object}
    ValidationRequest:
      type: object
      required: [license_key, product, installation_id, site_url]
      properties:
        license_key: {type: string}
        product: {type: string}
        installation_id: {type: string, minLength: 8, maxLength: 255}
        site_url: {type: string}
        product_version: {type: string, maxLength: 40}
        php_version: {type: string, maxLength: 30}
        cms_version: {type: string, maxLength: 40}
    ApiEnvelope:
      type: object
      properties:
        success: {type: boolean}
        data: {type: object}
        request_id: {type: string}
    ApiErrorEnvelope:
      type: object
      properties:
        success: {type: boolean, const: false}
        error:
          type: object
          properties:
            code: {type: string}
            message: {type: string}
            details: {type: object}
        request_id: {type: string}
  responses:
    LicenseSuccess:
      description: Operación de licencia completada
      content:
        application/json:
          schema: {$ref: '#/components/schemas/ApiEnvelope'}
    ApiError:
      description: Error normalizado de API
      content:
        application/json:
          schema: {$ref: '#/components/schemas/ApiErrorEnvelope'}
