{
  "openapi": "3.1.0",
  "info": {
    "title": "DevCleaner Public API Reference",
    "version": "1.0.0",
    "description": "Official public, machine-readable API reference for DevCleaner. It documents the small public web surface used by the DevCleaner macOS app and website. This specification intentionally excludes authenticated account, billing, administration, and local macOS cleanup operations.",
    "contact": { "name": "DevCleaner support", "url": "https://devcleaner.app/contact", "email": "hello@devcleaner.app" }
  },
  "servers": [{ "url": "https://devcleaner.app" }],
  "externalDocs": { "description": "DevCleaner product documentation", "url": "https://devcleaner.app/docs/" },
  "tags": [
    { "name": "Pricing", "description": "Public DevCleaner Pro pricing status." },
    { "name": "Ratings", "description": "Published product ratings and in-app rating submission." },
    { "name": "Feedback", "description": "Opt-in product feedback submission." }
  ],
  "paths": {
    "/api/early-bird-status.php": {
      "get": {
        "operationId": "getEarlyBirdStatus",
        "tags": ["Pricing"],
        "summary": "Get current DevCleaner Pro pricing status",
        "description": "Returns the currently active price and remaining early-bird availability.",
        "responses": {
          "200": { "description": "Pricing status", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EarlyBirdStatus" } } } },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/api/rating.php": {
      "get": {
        "operationId": "listPublishedRatings",
        "tags": ["Ratings"],
        "summary": "List published product ratings",
        "description": "Returns public ratings used by the DevCleaner homepage.",
        "responses": { "200": { "description": "Published ratings and their aggregate summary.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RatingsResponse" } } } } }
      },
      "post": {
        "operationId": "submitProductRating",
        "tags": ["Ratings"],
        "summary": "Submit a product rating",
        "description": "Submits one rating for an installed DevCleaner client. A stable installation identifier is required for rate limiting.",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RatingSubmission" } } } },
        "responses": {
          "200": { "description": "Rating accepted", "content": { "application/json": { "schema": { "type": "object", "required": ["ok", "published"], "properties": { "ok": { "type": "boolean" }, "published": { "type": "boolean" } } } } } },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "405": { "$ref": "#/components/responses/MethodNotAllowed" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/api/feedback.php": {
      "post": {
        "operationId": "submitFeedback",
        "tags": ["Feedback"],
        "summary": "Submit feedback to DevCleaner",
        "description": "Stores an opt-in feedback message. Requests are rate-limited by source address.",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FeedbackSubmission" } } } },
        "responses": {
          "200": { "description": "Feedback accepted", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "const": true } }, "required": ["ok"] } } } },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "405": { "$ref": "#/components/responses/MethodNotAllowed" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "EarlyBirdStatus": { "type": "object", "required": ["ok", "earlyBirdActive", "remaining", "price"], "properties": { "ok": { "const": true }, "earlyBirdActive": { "type": "boolean" }, "remaining": { "type": "integer", "minimum": 0 }, "percentage": { "type": "integer", "minimum": 0, "maximum": 100 }, "price": { "type": "number" }, "priceId": { "type": "string" }, "checkoutUrl": { "type": "string", "format": "uri" } } },
      "RatingSubmission": { "type": "object", "required": ["stars", "install_id"], "properties": { "stars": { "type": "integer", "minimum": 1, "maximum": 5, "description": "Star rating from 1 through 5." }, "install_id": { "type": "string", "maxLength": 64, "description": "Stable identifier supplied by an installed DevCleaner client." }, "comment": { "type": "string", "maxLength": 1000 }, "app_version": { "type": "string" }, "locale": { "type": "string" } } },
      "Rating": { "type": "object", "required": ["stars", "comment", "appVersion", "locale", "created", "author", "hasBody"], "properties": { "stars": { "type": "integer", "minimum": 1, "maximum": 5 }, "comment": { "type": "string" }, "appVersion": { "type": "string" }, "locale": { "type": "string" }, "created": { "type": "integer", "description": "Unix timestamp in seconds." }, "author": { "type": "string", "description": "Anonymous role label; no installation identifier is exposed." }, "hasBody": { "type": "boolean" } } },
      "RatingSummary": { "type": "object", "required": ["ratingCount", "ratingValue", "reviewCount", "commentCount"], "properties": { "ratingCount": { "type": "integer", "minimum": 0 }, "ratingValue": { "type": "number", "minimum": 0, "maximum": 5 }, "reviewCount": { "type": "integer", "minimum": 0 }, "commentCount": { "type": "integer", "minimum": 0 } } },
      "RatingsResponse": { "type": "object", "required": ["ratings", "summary"], "properties": { "ratings": { "type": "array", "items": { "$ref": "#/components/schemas/Rating" } }, "summary": { "$ref": "#/components/schemas/RatingSummary" } } },
      "DeviceContext": { "type": "object", "description": "Optional, user-submitted context from the installed app.", "properties": { "installId": { "type": "string", "maxLength": 64 }, "appVersion": { "type": "string", "maxLength": 200 }, "osVersion": { "type": "string", "maxLength": 200 }, "model": { "type": "string", "maxLength": 200 }, "arch": { "type": "string", "maxLength": 200 }, "locale": { "type": "string", "maxLength": 200 } } },
      "FeedbackSubmission": { "type": "object", "required": ["message"], "properties": { "message": { "type": "string", "minLength": 1, "maxLength": 5000 }, "category": { "type": "string", "maxLength": 40 }, "email": { "type": "string", "format": "email" }, "device": { "$ref": "#/components/schemas/DeviceContext" } } },
      "Error": { "type": "object", "description": "Stable JSON error envelope returned for documented client errors and server failures.", "required": ["ok", "error", "code", "hint"], "properties": { "ok": { "const": false }, "error": { "type": "string", "description": "Human-readable error message." }, "code": { "type": "string", "description": "Stable machine-readable error code for branching." }, "hint": { "type": "string", "description": "Human-readable corrective action." } }, "examples": [{ "ok": false, "error": "message required", "code": "validation_error", "hint": "Include a non-empty message field." }] }
    },
    "responses": {
      "ValidationError": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "MethodNotAllowed": { "description": "Unsupported HTTP method", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "RateLimited": { "description": "Request rate limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "InternalError": { "description": "Unexpected server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    }
  }
}
