{
  "openapi": "3.1.0",
  "info": {
    "title": "MouseHunt API",
    "version": "1.0.0",
    "description": "Unofficial, read-only API for public MouseHunt data."
  },
  "servers": [{ "url": "https://api.mouse.rip" }],
  "paths": {
    "/items": { "$ref": "#/components/pathItems/Items" },
    "/items/{id}": { "$ref": "#/components/pathItems/Item" },
    "/mice": { "$ref": "#/components/pathItems/Mice" },
    "/mice/{id}": { "$ref": "#/components/pathItems/Mouse" },
    "/search": {
      "get": {
        "summary": "Search items and mice for autocomplete",
        "parameters": [{ "$ref": "#/components/parameters/SearchQuery" }, { "$ref": "#/components/parameters/SearchTypes" }, { "$ref": "#/components/parameters/SearchLimit" }],
        "responses": { "200": { "description": "Relevance-ranked compact results", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SearchResponse" } } } }, "400": { "$ref": "#/components/responses/InvalidQuery" } }
      }
    },
    "/items/facets": { "get": { "summary": "Get available item filters and counts", "responses": { "200": { "$ref": "#/components/responses/Facets" } } } },
    "/mice/facets": { "get": { "summary": "Get available mouse filters and counts", "responses": { "200": { "$ref": "#/components/responses/Facets" } } } },
    "/status": { "get": { "summary": "Get API capabilities and current dataset versions", "responses": { "200": { "description": "API status", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Status" } } } } } } },
    "/versions": {
      "get": {
        "summary": "Get deployed data versions",
        "responses": { "200": { "description": "Data-file version map", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "string" } } } } } }
      }
    }
  },
  "components": {
    "pathItems": {
      "Items": { "get": { "summary": "List and query items", "parameters": [{ "$ref": "#/components/parameters/CollectionQuery" }], "responses": { "200": { "$ref": "#/components/responses/ItemCollection" }, "400": { "$ref": "#/components/responses/InvalidQuery" } } } },
      "Item": { "get": { "summary": "Get an item by numeric ID or type slug", "parameters": [{ "$ref": "#/components/parameters/Id" }, { "$ref": "#/components/parameters/CollectionQuery" }], "responses": { "200": { "$ref": "#/components/responses/Item" }, "400": { "$ref": "#/components/responses/InvalidQuery" }, "404": { "description": "Item not found" } } } },
      "Mice": { "get": { "summary": "List and query mice", "parameters": [{ "$ref": "#/components/parameters/CollectionQuery" }], "responses": { "200": { "$ref": "#/components/responses/MouseCollection" }, "400": { "$ref": "#/components/responses/InvalidQuery" } } } },
      "Mouse": { "get": { "summary": "Get a mouse by numeric ID or type slug", "parameters": [{ "$ref": "#/components/parameters/Id" }, { "$ref": "#/components/parameters/CollectionQuery" }], "responses": { "200": { "$ref": "#/components/responses/Mouse" }, "400": { "$ref": "#/components/responses/InvalidQuery" }, "404": { "description": "Mouse not found" } } } }
    },
    "parameters": {
      "Id": { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Numeric ID or type slug." },
      "CollectionQuery": { "name": "q", "in": "query", "schema": { "type": "string" }, "description": "Case-insensitive partial text search. Also accepts the backwards-compatible `search` parameter. Collections also support exact top-level filters, fields, ids, types, sort, offset, limit, and meta." },
      "SearchQuery": { "name": "q", "in": "query", "required": true, "schema": { "type": "string" }, "description": "Case-insensitive partial search term." },
      "SearchTypes": { "name": "types", "in": "query", "schema": { "type": "string", "example": "item,mouse" }, "description": "Optional comma-separated resources: item and/or mouse." },
      "SearchLimit": { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 0, "maximum": 50, "default": 10 }, "description": "Maximum number of results." }
    },
    "responses": {
      "ItemCollection": { "description": "Item collection. Use `meta=true` for the paginated envelope.", "headers": { "ETag": { "schema": { "type": "string" } }, "X-Total-Count": { "schema": { "type": "integer" } } }, "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Item" } } } } },
      "MouseCollection": { "description": "Mouse collection. Use `meta=true` for the paginated envelope.", "headers": { "ETag": { "schema": { "type": "string" } }, "X-Total-Count": { "schema": { "type": "integer" } } }, "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Mouse" } } } } },
      "Item": { "description": "Item", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Item" } } } },
      "Mouse": { "description": "Mouse", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Mouse" } } } },
      "Facets": { "description": "Facet values and matching-record counts", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Facets" } } } },
      "InvalidQuery": { "description": "Invalid query parameter", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    },
    "schemas": {
      "Item": { "type": "object", "required": ["id", "name", "type"], "properties": { "id": { "type": "integer" }, "name": { "type": "string" }, "type": { "type": "string" }, "classification": { "type": "string" }, "description": { "type": "string" } }, "additionalProperties": true },
      "Mouse": { "type": "object", "required": ["id", "name", "type"], "properties": { "id": { "type": "integer" }, "name": { "type": "string" }, "type": { "type": "string" }, "group": { "type": "string" }, "subgroup": { "type": "string" }, "points": { "type": "integer" }, "gold": { "type": "integer" } }, "additionalProperties": true },
      "SearchResponse": { "type": "object", "required": ["data", "meta"], "properties": { "data": { "type": "array", "items": { "type": "object", "required": ["id", "name", "resource", "type"], "properties": { "id": { "type": "integer" }, "image": { "type": "string" }, "name": { "type": "string" }, "resource": { "enum": ["item", "mouse"] }, "type": { "type": "string" } } } }, "meta": { "type": "object", "properties": { "count": { "type": "integer" }, "limit": { "type": "integer" }, "total": { "type": "integer" } } } } },
      "Facets": { "type": "object", "required": ["facets", "meta"], "properties": { "facets": { "type": "object", "additionalProperties": { "type": "array", "items": { "type": "object", "required": ["count", "value"], "properties": { "count": { "type": "integer" }, "value": { "type": "string" } } } } }, "meta": { "type": "object", "properties": { "total": { "type": "integer" } } } } },
      "Status": { "type": "object", "required": ["capabilities", "datasets", "status"], "properties": { "status": { "const": "ok" }, "capabilities": { "type": "object", "additionalProperties": { "type": "boolean" } }, "datasets": { "type": "object", "additionalProperties": { "type": "object", "properties": { "count": { "type": "integer" }, "version": { "type": ["string", "null"] } } } } } },
      "Error": { "type": "object", "required": ["error"], "properties": { "error": { "type": "object", "required": ["code", "message"], "properties": { "code": { "const": "invalid_query" }, "message": { "type": "string" } } } } }
    }
  }
}
