{
  "openapi": "3.1.0",
  "info": {
    "title": "MCAPI.TR Global Minecraft Server Status API",
    "version": "1.0.0",
    "description": "Free, globally available Minecraft Java and Bedrock server status API for developers worldwide. No account or API key is required.",
    "termsOfService": "https://mcapi.tr/terms",
    "contact": {
      "name": "MCAPI.TR",
      "url": "https://mcapi.tr/contact"
    },
    "license": {
      "name": "Service terms",
      "identifier": "LicenseRef-MCAPI-TR-Terms"
    }
  },
  "externalDocs": {
    "description": "Human-readable documentation and live playground",
    "url": "https://mcapi.tr/api-docs"
  },
  "servers": [
    {
      "url": "https://mcapi.tr/api/v1",
      "description": "Global production API"
    }
  ],
  "tags": [
    { "name": "Status", "description": "Minecraft server and API availability" },
    { "name": "Discovery", "description": "Recently verified online servers and platform statistics" },
    { "name": "Media", "description": "Server icons, banners, and widgets" }
  ],
  "paths": {
    "/status": {
      "get": {
        "operationId": "getApiHealth",
        "summary": "Check API health",
        "tags": ["Status"],
        "responses": {
          "200": {
            "description": "API is available",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/HealthResponse" }
              }
            }
          }
        }
      }
    },
    "/status/{address}": {
      "get": {
        "operationId": "getMinecraftServerStatus",
        "summary": "Get Minecraft server status",
        "description": "Queries a public Java, legacy Java, or Bedrock server and returns its current status. No API key is required.",
        "tags": ["Status"],
        "parameters": [
          {
            "name": "address",
            "in": "path",
            "required": true,
            "description": "Public hostname or IP, optionally followed by a port.",
            "schema": { "type": "string", "examples": ["mc.hypixel.net", "play.example.net:19132"] }
          },
          {
            "name": "legacy",
            "in": "query",
            "description": "Use the legacy Java ping protocol.",
            "schema": { "type": "boolean", "default": false }
          },
          {
            "name": "bedrock",
            "in": "query",
            "description": "Use the Minecraft Bedrock Edition protocol.",
            "schema": { "type": "boolean", "default": false }
          }
        ],
        "responses": {
          "200": {
            "description": "Current server status",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ServerStatus" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/trends": {
      "get": {
        "operationId": "getTrendingServers",
        "summary": "List recently verified online servers",
        "tags": ["Discovery"],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Page size from 1 to 50.",
            "schema": { "type": "integer", "minimum": 1, "maximum": 50, "default": 10 }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "Cursor returned by the previous response.",
            "schema": { "type": "string", "format": "uuid" }
          }
        ],
        "responses": {
          "200": {
            "description": "Trending verified servers",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/TrendResponse" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/stats": {
      "get": {
        "operationId": "getPlatformStatistics",
        "summary": "Get aggregate platform statistics",
        "tags": ["Discovery"],
        "responses": {
          "200": {
            "description": "Current aggregate statistics",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Statistics" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/icon/dynamic": {
      "get": {
        "operationId": "getServerIcon",
        "summary": "Get an optimized server icon",
        "description": "Returns the advertised server favicon or the branded MCAPI.TR fallback.",
        "tags": ["Media"],
        "parameters": [
          { "$ref": "#/components/parameters/AddressQuery" },
          {
            "name": "size",
            "in": "query",
            "schema": { "type": "integer", "minimum": 16, "maximum": 256, "default": 80 }
          },
          {
            "name": "format",
            "in": "query",
            "schema": { "type": "string", "enum": ["png", "webp"], "default": "png" }
          },
          { "$ref": "#/components/parameters/BedrockQuery" },
          { "$ref": "#/components/parameters/LegacyQuery" }
        ],
        "responses": {
          "200": {
            "description": "Server or branded fallback icon",
            "content": {
              "image/png": { "schema": { "type": "string", "contentEncoding": "binary" } },
              "image/webp": { "schema": { "type": "string", "contentEncoding": "binary" } }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/icon/sharp": {
      "get": {
        "operationId": "getRoundedServerIcon",
        "summary": "Get a rounded PNG server icon",
        "tags": ["Media"],
        "parameters": [
          { "$ref": "#/components/parameters/AddressQuery" },
          {
            "name": "size",
            "in": "query",
            "schema": { "type": "integer", "minimum": 32, "maximum": 512, "default": 128 }
          },
          { "$ref": "#/components/parameters/BedrockQuery" },
          { "$ref": "#/components/parameters/LegacyQuery" }
        ],
        "responses": {
          "200": {
            "description": "Rounded server icon",
            "content": {
              "image/png": { "schema": { "type": "string", "contentEncoding": "binary" } }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/banner/{address}": {
      "get": {
        "operationId": "getServerBanner",
        "summary": "Generate a Minecraft server status banner",
        "tags": ["Media"],
        "parameters": [
          {
            "name": "address",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          },
          {
            "name": "size",
            "in": "query",
            "schema": { "type": "string", "enum": ["small", "normal", "large"], "default": "normal" }
          },
          {
            "name": "style",
            "in": "query",
            "schema": { "type": "string", "enum": ["modern", "classic"], "default": "modern" }
          }
        ],
        "responses": {
          "200": {
            "description": "PNG status banner",
            "content": {
              "image/png": { "schema": { "type": "string", "contentEncoding": "binary" } }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/widget/{size}/{address}": {
      "get": {
        "operationId": "getServerWidget",
        "summary": "Get an embeddable server status widget",
        "tags": ["Media"],
        "parameters": [
          {
            "name": "size",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "enum": ["small", "normal", "large"] }
          },
          {
            "name": "address",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          },
          {
            "name": "theme",
            "in": "query",
            "schema": { "type": "string", "enum": ["dark", "light"], "default": "dark" }
          }
        ],
        "responses": {
          "200": {
            "description": "Embeddable HTML widget",
            "content": {
              "text/html": { "schema": { "type": "string" } }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "AddressQuery": {
        "name": "address",
        "in": "query",
        "required": true,
        "description": "Public Minecraft server hostname or IP, optionally with a port.",
        "schema": { "type": "string" }
      },
      "BedrockQuery": {
        "name": "bedrock",
        "in": "query",
        "schema": { "type": "boolean", "default": false }
      },
      "LegacyQuery": {
        "name": "legacy",
        "in": "query",
        "schema": { "type": "boolean", "default": false }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid address or query parameter",
        "content": {
          "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } }
        }
      },
      "NotFound": {
        "description": "Minecraft server is offline or unreachable",
        "content": {
          "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } }
        }
      },
      "RateLimited": {
        "description": "Per-minute request limit exceeded",
        "content": {
          "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } }
        }
      }
    },
    "schemas": {
      "HealthResponse": {
        "type": "object",
        "required": ["status", "timestamp", "service", "version"],
        "properties": {
          "status": { "type": "string", "const": "OK" },
          "timestamp": { "type": "string", "format": "date-time" },
          "service": { "type": "string", "examples": ["mcapi.tr-engine"] },
          "version": { "type": "string" }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "status": { "type": "string" },
          "error": { "type": "string" },
          "message": { "type": "string" }
        }
      },
      "Query": {
        "type": "object",
        "properties": {
          "host": { "type": "string" },
          "port": { "type": "integer" },
          "legacy": { "type": "boolean" },
          "bedrock": { "type": "boolean" }
        }
      },
      "Players": {
        "type": ["object", "null"],
        "properties": {
          "online": { "type": "integer", "minimum": 0 },
          "max": { "type": "integer", "minimum": 0 },
          "sample": { "type": "array", "items": { "type": "object", "additionalProperties": true } }
        }
      },
      "Motd": {
        "type": ["object", "null"],
        "properties": {
          "raw": { "type": "string" },
          "clean": { "type": "string" },
          "html": { "type": "string" },
          "raw_lines": { "type": "array", "items": { "type": "string" } },
          "clean_lines": { "type": "array", "items": { "type": "string" } }
        }
      },
      "ServerStatus": {
        "type": "object",
        "required": ["query", "online"],
        "properties": {
          "query": { "$ref": "#/components/schemas/Query" },
          "server_id": { "type": ["string", "null"], "format": "uuid" },
          "ip_address": { "type": ["string", "null"] },
          "icmp": { "type": ["boolean", "null"] },
          "online": { "type": "boolean" },
          "error": { "type": ["string", "null"] },
          "version": {
            "type": ["object", "null"],
            "properties": {
              "name": { "type": "string" },
              "protocol": { "type": "integer" }
            }
          },
          "players": { "$ref": "#/components/schemas/Players" },
          "motd": { "$ref": "#/components/schemas/Motd" },
          "favicon": { "type": ["string", "null"], "description": "Data URL when advertised by the server." },
          "roundTripLatency": { "type": ["number", "null"], "minimum": 0 },
          "stale": { "type": "boolean" },
          "checked_at": { "type": "string", "format": "date-time" }
        },
        "additionalProperties": true
      },
      "TrendServer": {
        "type": "object",
        "required": ["hostname", "port", "is_online", "stale"],
        "properties": {
          "server_id": { "type": "string", "format": "uuid" },
          "hostname": { "type": "string" },
          "address": { "type": "string" },
          "port": { "type": "integer" },
          "edition": { "type": "string", "enum": ["java", "bedrock"] },
          "trend_score": { "type": "number" },
          "is_online": { "type": "boolean", "const": true },
          "stale": { "type": "boolean", "const": false },
          "checked_at": { "type": "string", "format": "date-time" },
          "players_online": { "type": "integer" },
          "players_max": { "type": "integer" },
          "record_players": { "type": "integer" },
          "uptime_percentage": { "type": "number" }
        },
        "additionalProperties": true
      },
      "TrendResponse": {
        "type": "object",
        "required": ["success", "data", "meta"],
        "properties": {
          "success": { "type": "boolean", "const": true },
          "data": { "type": "array", "items": { "$ref": "#/components/schemas/TrendServer" } },
          "meta": {
            "type": "object",
            "properties": {
              "nextCursor": { "type": ["string", "null"] },
              "hasNext": { "type": "boolean" },
              "limit": { "type": "integer" }
            }
          }
        }
      },
      "Statistics": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "totalRequests": { "type": "integer" },
          "apiRequests": { "type": "integer" },
          "serverQueries": { "type": "integer" },
          "totalChecks": { "type": "integer" },
          "onlineServers": { "type": "integer" },
          "offlineServers": { "type": "integer" },
          "activePlayers": { "type": "integer" },
          "onlineRate": { "type": "number" }
        }
      }
    }
  }
}
