{
  "openapi": "3.1.0",
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "info": {
    "title": "BSS Index API",
    "version": "2.2.0",
    "summary": "Item values, price history and beequip rolls for Bee Swarm Simulator.",
    "description": "A read-only, public JSON API for the Bee Swarm Simulator value list.\n\nEvery value is a real JSON number (never a string), every image URL is absolute, every document is versioned and self-describing, and CORS is open (`Access-Control-Allow-Origin: *`) so the API can be called straight from a browser on any domain.\n\nThe catalogue currently holds 330 items across 18 categories. Start with `/api/v1/index.json`.",
    "license": {
      "name": "MIT",
      "identifier": "MIT"
    }
  },
  "servers": [
    {
      "url": "https://bss-index.vercel.app/api/v1",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "meta",
      "description": "Discovery, documentation and the OpenAPI description."
    },
    {
      "name": "data",
      "description": "Items, categories, price history and market statistics."
    }
  ],
  "paths": {
    "/index.json": {
      "get": {
        "operationId": "getIndex",
        "summary": "API discovery document",
        "description": "Discovery document. Lists the API version, the origin, the item and category counts, every category, the demand/stability legends and the full endpoint catalogue. Start here.",
        "tags": [
          "meta"
        ],
        "responses": {
          "200": {
            "description": "Discovery document. Lists the API version, the origin, the item and category counts, every category, the demand/stability legends and the full endpoint catalogue. Start here.\n\nExample: https://bss-index.vercel.app/api/v1/index.json",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                },
                "description": "Always \"*\" — the API is readable from any origin."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Index"
                }
              }
            }
          }
        }
      }
    },
    "/items.json": {
      "get": {
        "operationId": "getItems",
        "summary": "All items",
        "description": "Every item of the catalogue in the compact shape, sorted by value descending. One array, no pagination needed.",
        "tags": [
          "data"
        ],
        "responses": {
          "200": {
            "description": "Every item of the catalogue in the compact shape, sorted by value descending. One array, no pagination needed.\n\nExample: https://bss-index.vercel.app/api/v1/items.json",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                },
                "description": "Always \"*\" — the API is readable from any origin."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Item"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/items/{slug}.json": {
      "get": {
        "operationId": "getItem",
        "summary": "One item, full detail",
        "description": "Full record for a single item: the compact fields plus description, the dated price history, the beequip rolls and up to 10 related items.",
        "tags": [
          "data"
        ],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Item slug, e.g. \"star-cub\". See /api/v1/search-index.json for the full list.",
            "schema": {
              "type": "string"
            },
            "example": "star-cub"
          }
        ],
        "responses": {
          "200": {
            "description": "Full record for a single item: the compact fields plus description, the dated price history, the beequip rolls and up to 10 related items.\n\nExample: https://bss-index.vercel.app/api/v1/items/star-cub.json",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                },
                "description": "Always \"*\" — the API is readable from any origin."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemDetail"
                }
              }
            }
          },
          "404": {
            "description": "Unknown slug — check /api/v1/search-index.json for the valid slugs."
          }
        }
      }
    },
    "/items/{slug}/history.json": {
      "get": {
        "operationId": "getHistory",
        "summary": "Price history of one item",
        "description": "Price history of a single item as two parallel arrays (dates + prices) plus min/max/average and the 7d/30d changes. Only items with a recorded history have this file.",
        "tags": [
          "data"
        ],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Item slug, e.g. \"star-cub\".",
            "schema": {
              "type": "string"
            },
            "example": "star-cub"
          }
        ],
        "responses": {
          "200": {
            "description": "Price history of a single item as two parallel arrays (dates + prices) plus min/max/average and the 7d/30d changes. Only items with a recorded history have this file.\n\nExample: https://bss-index.vercel.app/api/v1/items/star-cub/history.json",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                },
                "description": "Always \"*\" — the API is readable from any origin."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/History"
                }
              }
            }
          },
          "404": {
            "description": "Unknown slug — check /api/v1/search-index.json for the valid slugs."
          }
        }
      }
    },
    "/categories.json": {
      "get": {
        "operationId": "getCategories",
        "summary": "All categories",
        "description": "Every category with its slug, English name, Russian name, item count and value statistics (min, max, average, total).",
        "tags": [
          "data"
        ],
        "responses": {
          "200": {
            "description": "Every category with its slug, English name, Russian name, item count and value statistics (min, max, average, total).\n\nExample: https://bss-index.vercel.app/api/v1/categories.json",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                },
                "description": "Always \"*\" — the API is readable from any origin."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Category"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/categories/{slug}/items.json": {
      "get": {
        "operationId": "getCategoryItems",
        "summary": "Items of one category",
        "description": "All items of one category in the same compact shape as /api/v1/items.json, sorted by value descending.",
        "tags": [
          "data"
        ],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Category slug, e.g. \"bee-stickers\". See /api/v1/categories.json for the full list.",
            "schema": {
              "type": "string"
            },
            "example": "star-cub"
          }
        ],
        "responses": {
          "200": {
            "description": "All items of one category in the same compact shape as /api/v1/items.json, sorted by value descending.\n\nExample: https://bss-index.vercel.app/api/v1/categories/bee-stickers/items.json",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                },
                "description": "Always \"*\" — the API is readable from any origin."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Item"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Unknown slug — check /api/v1/search-index.json for the valid slugs."
          }
        }
      }
    },
    "/search": {
      "get": {
        "operationId": "getSearch",
        "summary": "Search items",
        "description": "Server-side search. Matches the name in either language, the slug, and the community slang for each category (so a Russian query finds the right group too). Returns items ranked by relevance, then by value.",
        "tags": [
          "data"
        ],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Search term, e.g. \"bee\", \"star cub\", \"kub\".",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "description": "Filter by category slug, e.g. \"vouchers\", \"cub-skins\".",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "relevance (default), value, value-asc, name, change.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Items per page, 1-100, default 25.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Offset for pagination, default 0.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Server-side search. Matches the name in either language, the slug, and the community slang for each category (so a Russian query finds the right group too). Returns items ranked by relevance, then by value.\n\nExample: https://bss-index.vercel.app/api/v1/search?q=bee&limit=10",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                },
                "description": "Always \"*\" — the API is readable from any origin."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "query": {
                      "type": "string",
                      "nullable": true
                    },
                    "category": {
                      "type": "string",
                      "nullable": true
                    },
                    "sort": {
                      "type": "string"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Item"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Unknown slug — check /api/v1/search-index.json for the valid slugs."
          }
        }
      }
    },
    "/changes.json": {
      "get": {
        "operationId": "getChanges",
        "summary": "Market movers",
        "description": "Market movers: the 10 biggest gainers and the 10 biggest losers over the last 7 days, with their 30 day change. Items without enough history are skipped.",
        "tags": [
          "data"
        ],
        "responses": {
          "200": {
            "description": "Market movers: the 10 biggest gainers and the 10 biggest losers over the last 7 days, with their 30 day change. Items without enough history are skipped.\n\nExample: https://bss-index.vercel.app/api/v1/changes.json",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                },
                "description": "Always \"*\" — the API is readable from any origin."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "gainers": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Mover"
                      }
                    },
                    "losers": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Mover"
                      }
                    },
                    "updated": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/stats.json": {
      "get": {
        "operationId": "getStats",
        "summary": "Market statistics",
        "description": "Market summary: item count, total/average/median/min/max value and how many items carry a price history.",
        "tags": [
          "data"
        ],
        "responses": {
          "200": {
            "description": "Market summary: item count, total/average/median/min/max value and how many items carry a price history.\n\nExample: https://bss-index.vercel.app/api/v1/stats.json",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                },
                "description": "Always \"*\" — the API is readable from any origin."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Stats"
                }
              }
            }
          }
        }
      }
    },
    "/search-index.json": {
      "get": {
        "operationId": "getSearchIndex",
        "summary": "Lean search index",
        "description": "Small, lean index (slug, English and Russian names, English category, value) meant to be downloaded once and filtered client-side for instant search. No history, no colours.",
        "tags": [
          "data"
        ],
        "responses": {
          "200": {
            "description": "Small, lean index (slug, English and Russian names, English category, value) meant to be downloaded once and filtered client-side for instant search. No history, no colours.\n\nExample: https://bss-index.vercel.app/api/v1/search-index.json",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                },
                "description": "Always \"*\" — the API is readable from any origin."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SearchEntry"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenapi",
        "summary": "OpenAPI 3.1 description",
        "description": "OpenAPI 3.1 description of this API. Point your API client, Swagger UI or Redoc at it.",
        "tags": [
          "meta"
        ],
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 description of this API. Point your API client, Swagger UI or Redoc at it.\n\nExample: https://bss-index.vercel.app/api/v1/openapi.json",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                },
                "description": "Always \"*\" — the API is readable from any origin."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "This OpenAPI 3.1 document."
                }
              }
            }
          }
        }
      }
    },
    "/docs.html": {
      "get": {
        "operationId": "getDocs",
        "summary": "Human readable reference",
        "description": "Human readable API reference (this page).",
        "tags": [
          "meta"
        ],
        "responses": {
          "200": {
            "description": "Human readable API reference (this page).\n\nExample: https://bss-index.vercel.app/api/v1/docs.html",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                },
                "description": "Always \"*\" — the API is readable from any origin."
              }
            },
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Item": {
        "type": "object",
        "description": "The compact item shape used by /items.json and the category files.",
        "required": [
          "slug",
          "id",
          "name",
          "nameRu",
          "category",
          "categoryRu",
          "categorySlug",
          "value",
          "valueLow",
          "valueHigh",
          "demand",
          "demandEn",
          "stability",
          "stabilityEn",
          "change7d",
          "change30d",
          "image",
          "url",
          "hasHistory"
        ],
        "properties": {
          "slug": {
            "type": "string",
            "description": "URL-safe identifier, identical to the /item/<slug>/ page."
          },
          "id": {
            "type": "string",
            "description": "Stable internal id of the item."
          },
          "name": {
            "type": "string",
            "description": "English name of the item, e.g. \"Autumn Sunhat\"."
          },
          "nameRu": {
            "type": [
              "string",
              "null"
            ],
            "description": "Russian name of the item, e.g. \"Осенняя панама\". Null when the item has no separate Russian name."
          },
          "category": {
            "type": "string",
            "description": "English category name, e.g. \"Cub Skins\"."
          },
          "categoryRu": {
            "type": "string",
            "description": "Russian category name, e.g. \"Скины на каба\"."
          },
          "categorySlug": {
            "type": "string",
            "description": "Slugified English category name, e.g. \"cub-skins\"."
          },
          "value": {
            "type": "number",
            "description": "Current value in honey/beeswax units."
          },
          "valueLow": {
            "type": "number",
            "description": "Lower bound of the accepted price range."
          },
          "valueHigh": {
            "type": "number",
            "description": "Upper bound of the accepted price range."
          },
          "demand": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "Low",
              "Average",
              "High",
              "Hype",
              null
            ],
            "description": "Demand, English label."
          },
          "demandRu": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "Низкий",
              "Средний",
              "Высокий",
              "Хайп",
              null
            ],
            "description": "Demand, Russian label."
          },
          "stability": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "Rising",
              "Stable",
              "Falling",
              null
            ],
            "description": "Price stability, English label."
          },
          "stabilityRu": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "Растет",
              "Стабильно",
              "Падает",
              null
            ],
            "description": "Price stability, Russian label."
          },
          "change7d": {
            "type": [
              "number",
              "null"
            ],
            "description": "Price change over the last 7 days in percent, null when there is not enough history."
          },
          "change30d": {
            "type": [
              "number",
              "null"
            ],
            "description": "Price change over the last 30 days in percent, null when there is not enough history."
          },
          "image": {
            "type": [
              "string",
              "null"
            ],
            "description": "Absolute image URL."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Absolute URL of the item page on the site."
          },
          "hasHistory": {
            "type": "boolean",
            "description": "True when the item has a recorded price history."
          }
        }
      },
      "ItemDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Item"
          },
          {
            "type": "object",
            "required": [
              "description",
              "historicalDates",
              "historicalPrices",
              "rolls",
              "related"
            ],
            "properties": {
              "description": {
                "type": "string",
                "description": "Factual English summary of the item and its market state."
              },
              "descriptionRu": {
                "type": "string",
                "description": "The original Russian market description from the source."
              },
              "historicalDates": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "date"
                },
                "description": "Dates of the recorded price points, aligned with historicalPrices."
              },
              "historicalPrices": {
                "type": "array",
                "items": {
                  "type": "number"
                },
                "description": "Recorded prices, aligned with historicalDates."
              },
              "rolls": {
                "type": "array",
                "description": "Beequip rolls (empty for non-beequip items).",
                "items": {
                  "type": "object",
                  "properties": {
                    "group": {
                      "type": "string"
                    },
                    "rollName": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "value": {
                      "type": "number"
                    },
                    "valueLow": {
                      "type": "number"
                    },
                    "valueHigh": {
                      "type": "number"
                    },
                    "valueText": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Original price expression, e.g. \">=100\"."
                    },
                    "isFloor": {
                      "type": "boolean",
                      "description": "True when the price is a lower bound rather than an exact value."
                    },
                    "demand": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "enum": [
                        "Low",
                        "Average",
                        "High",
                        "Hype",
                        null
                      ]
                    },
                    "demandRu": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              },
              "related": {
                "type": "array",
                "description": "Up to 10 related items: same category first, then the most valuable overall.",
                "items": {
                  "type": "object",
                  "properties": {
                    "slug": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "nameRu": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "value": {
                      "type": "number"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "History": {
        "type": "object",
        "required": [
          "slug",
          "name",
          "nameRu",
          "dates",
          "prices",
          "change7d",
          "change30d",
          "min",
          "max",
          "average"
        ],
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "description": "English name of the item."
          },
          "nameRu": {
            "type": [
              "string",
              "null"
            ],
            "description": "Russian name of the item, null when there is none."
          },
          "dates": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "date"
            }
          },
          "prices": {
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "change7d": {
            "type": [
              "number",
              "null"
            ]
          },
          "change30d": {
            "type": [
              "number",
              "null"
            ]
          },
          "min": {
            "type": [
              "number",
              "null"
            ]
          },
          "max": {
            "type": [
              "number",
              "null"
            ]
          },
          "average": {
            "type": [
              "number",
              "null"
            ]
          }
        }
      },
      "Category": {
        "type": "object",
        "required": [
          "slug",
          "name",
          "nameRu",
          "categoryRu",
          "count",
          "minValue",
          "maxValue",
          "averageValue",
          "totalValue"
        ],
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "description": "English category name, e.g. \"Cub Skins\"."
          },
          "nameRu": {
            "type": "string",
            "description": "Russian category name, e.g. \"Скины на каба\"."
          },
          "categoryRu": {
            "type": "string",
            "description": "Russian category name — same value as nameRu, kept so the key is the same on items and on categories."
          },
          "count": {
            "type": "integer"
          },
          "minValue": {
            "type": "number"
          },
          "maxValue": {
            "type": "number"
          },
          "averageValue": {
            "type": "number"
          },
          "totalValue": {
            "type": "number"
          }
        }
      },
      "Mover": {
        "type": "object",
        "required": [
          "slug",
          "name",
          "nameRu",
          "value",
          "change7d",
          "change30d"
        ],
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "description": "English name of the item."
          },
          "nameRu": {
            "type": [
              "string",
              "null"
            ],
            "description": "Russian name of the item, null when there is none."
          },
          "value": {
            "type": "number"
          },
          "change7d": {
            "type": [
              "number",
              "null"
            ]
          },
          "change30d": {
            "type": [
              "number",
              "null"
            ]
          }
        }
      },
      "Stats": {
        "type": "object",
        "required": [
          "itemCount",
          "totalValue",
          "averageValue",
          "medianValue",
          "minValue",
          "maxValue",
          "itemsWithHistory",
          "lastUpdated"
        ],
        "properties": {
          "itemCount": {
            "type": "integer"
          },
          "totalValue": {
            "type": "number"
          },
          "averageValue": {
            "type": "number"
          },
          "medianValue": {
            "type": "number"
          },
          "minValue": {
            "type": "number"
          },
          "maxValue": {
            "type": "number"
          },
          "itemsWithHistory": {
            "type": "integer"
          },
          "lastUpdated": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SearchEntry": {
        "type": "object",
        "required": [
          "slug",
          "name",
          "nameRu",
          "category",
          "categorySlug",
          "value"
        ],
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "description": "English name of the item."
          },
          "nameRu": {
            "type": [
              "string",
              "null"
            ],
            "description": "Russian name of the item, null when there is none."
          },
          "category": {
            "type": "string",
            "description": "English category name, e.g. \"Cub Skins\"."
          },
          "categorySlug": {
            "type": "string",
            "description": "Slugified English category name, e.g. \"cub-skins\"."
          },
          "value": {
            "type": "number"
          }
        }
      },
      "Index": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "origin": {
            "type": "string"
          },
          "generated": {
            "type": "string",
            "format": "date-time"
          },
          "itemCount": {
            "type": "integer"
          },
          "categoryCount": {
            "type": "integer"
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "endpoints": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "demandLevels": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "stabilityLevels": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      }
    }
  }
}