{
  "openapi": "3.1.0",
  "info": {
    "title": "WooCommerce Licensed Product API",
    "description": "REST API for validating and managing software licenses bound to domains. This API allows external applications to validate license keys, check license status, and activate licenses on specific domains.\n\n## Response Signing (Optional)\n\nWhen the server is configured with `WC_LICENSE_SERVER_SECRET`, all API responses include cryptographic signatures for tamper protection:\n\n- `X-License-Signature`: HMAC-SHA256 signature of the response\n- `X-License-Timestamp`: Unix timestamp when the response was generated\n\nSignature verification prevents man-in-the-middle attacks and ensures response integrity. Use the `magdev/wc-licensed-product-client` library's `SecureLicenseClient` class to automatically verify signatures.",
    "version": "0.3.2",
    "contact": {
      "name": "Marco Graetsch",
      "url": "https://src.bundespruefstelle.ch/magdev",
      "email": "magdev3.0@gmail.com"
    },
    "license": {
      "name": "GPL-2.0-or-later",
      "url": "https://www.gnu.org/licenses/gpl-2.0.html"
    }
  },
  "servers": [
    {
      "url": "{baseUrl}/wp-json/wc-licensed-product/v1",
      "description": "WordPress REST API endpoint",
      "variables": {
        "baseUrl": {
          "default": "https://example.com",
          "description": "The base URL of your WordPress installation"
        }
      }
    }
  ],
  "paths": {
    "/validate": {
      "post": {
        "operationId": "validateLicense",
        "summary": "Validate a license key for a domain",
        "description": "Validates whether a license key is valid for a specific domain. Checks license status, expiration, and domain binding. This is the primary endpoint for software to verify license validity.",
        "tags": ["License Validation"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ValidateRequest"
              },
              "example": {
                "license_key": "ABCD-1234-EFGH-5678",
                "domain": "example.com"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/ValidateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "License is valid for the specified domain",
            "headers": {
              "X-License-Signature": {
                "$ref": "#/components/headers/X-License-Signature"
              },
              "X-License-Timestamp": {
                "$ref": "#/components/headers/X-License-Timestamp"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidateSuccessResponse"
                },
                "example": {
                  "valid": true,
                  "license": {
                    "product_id": 123,
                    "expires_at": "2027-01-21",
                    "version_id": 5
                  }
                }
              }
            }
          },
          "403": {
            "description": "License validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidateErrorResponse"
                },
                "examples": {
                  "license_not_found": {
                    "summary": "License key not found",
                    "value": {
                      "valid": false,
                      "error": "license_not_found",
                      "message": "License key not found."
                    }
                  },
                  "license_revoked": {
                    "summary": "License has been revoked",
                    "value": {
                      "valid": false,
                      "error": "license_revoked",
                      "message": "This license has been revoked."
                    }
                  },
                  "license_expired": {
                    "summary": "License has expired",
                    "value": {
                      "valid": false,
                      "error": "license_expired",
                      "message": "This license has expired."
                    }
                  },
                  "license_inactive": {
                    "summary": "License is inactive",
                    "value": {
                      "valid": false,
                      "error": "license_inactive",
                      "message": "This license is inactive."
                    }
                  },
                  "domain_mismatch": {
                    "summary": "License not valid for this domain",
                    "value": {
                      "valid": false,
                      "error": "domain_mismatch",
                      "message": "This license is not valid for this domain."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitExceeded"
          }
        }
      }
    },
    "/status": {
      "post": {
        "operationId": "checkStatus",
        "summary": "Get license status information",
        "description": "Retrieves detailed status information for a license key, including validity, domain binding, expiration date, and activation counts.",
        "tags": ["License Status"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StatusRequest"
              },
              "example": {
                "license_key": "ABCD-1234-EFGH-5678"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/StatusRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "License status retrieved successfully",
            "headers": {
              "X-License-Signature": {
                "$ref": "#/components/headers/X-License-Signature"
              },
              "X-License-Timestamp": {
                "$ref": "#/components/headers/X-License-Timestamp"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatusResponse"
                },
                "example": {
                  "valid": true,
                  "status": "active",
                  "domain": "example.com",
                  "expires_at": "2027-01-21",
                  "activations_count": 1,
                  "max_activations": 3
                }
              }
            }
          },
          "404": {
            "description": "License key not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "valid": false,
                  "error": "license_not_found",
                  "message": "License key not found."
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitExceeded"
          }
        }
      }
    },
    "/activate": {
      "post": {
        "operationId": "activateLicense",
        "summary": "Activate a license on a domain",
        "description": "Activates a license key on a specific domain. If the license is already activated on the same domain, returns success. If activating on a new domain, the old domain binding is replaced (single-domain licenses).",
        "tags": ["License Activation"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ActivateRequest"
              },
              "example": {
                "license_key": "ABCD-1234-EFGH-5678",
                "domain": "newdomain.com"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/ActivateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "License activated successfully or already activated",
            "headers": {
              "X-License-Signature": {
                "$ref": "#/components/headers/X-License-Signature"
              },
              "X-License-Timestamp": {
                "$ref": "#/components/headers/X-License-Timestamp"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActivateSuccessResponse"
                },
                "examples": {
                  "activated": {
                    "summary": "License activated on new domain",
                    "value": {
                      "success": true,
                      "message": "License activated successfully."
                    }
                  },
                  "already_activated": {
                    "summary": "License already activated on this domain",
                    "value": {
                      "success": true,
                      "message": "License is already activated for this domain."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Activation failed due to license restrictions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "license_invalid": {
                    "summary": "License is not valid",
                    "value": {
                      "success": false,
                      "error": "license_invalid",
                      "message": "This license is not valid."
                    }
                  },
                  "max_activations_reached": {
                    "summary": "Maximum activations reached",
                    "value": {
                      "success": false,
                      "error": "max_activations_reached",
                      "message": "Maximum number of activations reached."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "License key not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "license_not_found",
                  "message": "License key not found."
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitExceeded"
          },
          "500": {
            "description": "Server error during activation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "activation_failed",
                  "message": "Failed to activate license."
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ValidateRequest": {
        "type": "object",
        "required": ["license_key", "domain"],
        "properties": {
          "license_key": {
            "type": "string",
            "description": "The license key to validate (format: XXXX-XXXX-XXXX-XXXX)",
            "maxLength": 64,
            "example": "ABCD-1234-EFGH-5678"
          },
          "domain": {
            "type": "string",
            "description": "The domain to validate the license against",
            "maxLength": 255,
            "example": "example.com"
          }
        }
      },
      "ValidateSuccessResponse": {
        "type": "object",
        "properties": {
          "valid": {
            "type": "boolean",
            "const": true,
            "description": "Indicates the license is valid"
          },
          "license": {
            "type": "object",
            "properties": {
              "product_id": {
                "type": "integer",
                "description": "WooCommerce product ID associated with the license"
              },
              "expires_at": {
                "type": ["string", "null"],
                "format": "date",
                "description": "Expiration date (null for lifetime licenses)"
              },
              "version_id": {
                "type": ["integer", "null"],
                "description": "Product version ID if license is bound to a version"
              }
            }
          }
        }
      },
      "ValidateErrorResponse": {
        "type": "object",
        "properties": {
          "valid": {
            "type": "boolean",
            "const": false,
            "description": "Indicates validation failed"
          },
          "error": {
            "type": "string",
            "enum": ["license_not_found", "license_revoked", "license_expired", "license_inactive", "domain_mismatch"],
            "description": "Error code for programmatic handling"
          },
          "message": {
            "type": "string",
            "description": "Human-readable error message"
          }
        }
      },
      "StatusRequest": {
        "type": "object",
        "required": ["license_key"],
        "properties": {
          "license_key": {
            "type": "string",
            "description": "The license key to check",
            "example": "ABCD-1234-EFGH-5678"
          }
        }
      },
      "StatusResponse": {
        "type": "object",
        "properties": {
          "valid": {
            "type": "boolean",
            "description": "Whether the license is currently valid"
          },
          "status": {
            "type": "string",
            "enum": ["active", "inactive", "expired", "revoked"],
            "description": "Current license status"
          },
          "domain": {
            "type": "string",
            "description": "Domain the license is bound to"
          },
          "expires_at": {
            "type": ["string", "null"],
            "format": "date",
            "description": "Expiration date (null for lifetime licenses)"
          },
          "activations_count": {
            "type": "integer",
            "description": "Current number of activations"
          },
          "max_activations": {
            "type": "integer",
            "description": "Maximum allowed activations"
          }
        }
      },
      "ActivateRequest": {
        "type": "object",
        "required": ["license_key", "domain"],
        "properties": {
          "license_key": {
            "type": "string",
            "description": "The license key to activate",
            "example": "ABCD-1234-EFGH-5678"
          },
          "domain": {
            "type": "string",
            "description": "The domain to activate the license on",
            "example": "newdomain.com"
          }
        }
      },
      "ActivateSuccessResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "const": true,
            "description": "Indicates activation was successful"
          },
          "message": {
            "type": "string",
            "description": "Human-readable success message"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "const": false,
            "description": "Indicates the operation failed"
          },
          "valid": {
            "type": "boolean",
            "const": false,
            "description": "Indicates validation failed (for validation endpoints)"
          },
          "error": {
            "type": "string",
            "description": "Error code for programmatic handling"
          },
          "message": {
            "type": "string",
            "description": "Human-readable error message"
          }
        }
      },
      "RateLimitResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "string",
            "const": "rate_limit_exceeded"
          },
          "message": {
            "type": "string",
            "example": "Too many requests. Please try again later."
          },
          "retry_after": {
            "type": "integer",
            "description": "Seconds until rate limit resets"
          }
        }
      }
    },
    "responses": {
      "RateLimitExceeded": {
        "description": "Rate limit exceeded (30 requests per minute per IP)",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Seconds until the rate limit resets"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/RateLimitResponse"
            },
            "example": {
              "success": false,
              "error": "rate_limit_exceeded",
              "message": "Too many requests. Please try again later.",
              "retry_after": 45
            }
          }
        }
      }
    },
    "headers": {
      "X-License-Signature": {
        "description": "HMAC-SHA256 signature of the response body for tamper protection. Only present when server is configured with WC_LICENSE_SERVER_SECRET. Signature format: hex-encoded HMAC-SHA256 of (timestamp + ':' + canonical_json_body) using a per-license derived key.",
        "schema": {
          "type": "string",
          "pattern": "^[a-f0-9]{64}$",
          "example": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456"
        },
        "required": false
      },
      "X-License-Timestamp": {
        "description": "Unix timestamp when the response was generated. Used together with X-License-Signature to prevent replay attacks. Only present when server is configured with WC_LICENSE_SERVER_SECRET.",
        "schema": {
          "type": "string",
          "pattern": "^[0-9]+$",
          "example": "1737550000"
        },
        "required": false
      }
    }
  },
  "tags": [
    {
      "name": "License Validation",
      "description": "Validate license keys against domains"
    },
    {
      "name": "License Status",
      "description": "Check license status and details"
    },
    {
      "name": "License Activation",
      "description": "Activate licenses on domains"
    }
  ]
}
