{
  "openapi": "3.1.0",
  "info": {
    "title": "SupplyClub Public Read API",
    "description": "Public read-only endpoints for the SupplyClub wholesale food packaging catalog (mysupplyclub.com). Rate-limited: verified crawlers pass freely, normal clients 60 req/min. For richer agent access (search, filters, paging), see the MCP server at https://mysupplyclub.com/api/mcp — no authentication required (server card: https://mysupplyclub.com/.well-known/mcp.json).",
    "version": "1.0.0",
    "contact": {
      "email": "info@mysupplyclub.com"
    }
  },
  "servers": [{ "url": "https://mysupplyclub.com" }],
  "paths": {
    "/api/products/by-ids": {
      "get": {
        "operationId": "getProductsByIds",
        "summary": "Fetch full product data for a list of product IDs",
        "parameters": [
          {
            "name": "ids",
            "in": "query",
            "required": true,
            "description": "Comma-separated WooCommerce product IDs (max 100)",
            "schema": { "type": "string", "example": "123,456,789" }
          }
        ],
        "responses": {
          "200": {
            "description": "Products found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "products": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Product" }
                    },
                    "found": { "type": "integer" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/Error" },
          "429": { "$ref": "#/components/responses/Error" },
          "404": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/api/pricing/get-prices-for-products": {
      "post": {
        "operationId": "getPricesForProducts",
        "summary": "Calculate guest or member prices for a list of products",
        "description": "Anonymous callers receive guest pricing (zone-based discount off regular price). Authenticated members receive their member pricing.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["productIds", "regularPrices"],
                "properties": {
                  "productIds": {
                    "type": "array",
                    "items": { "type": "integer" },
                    "description": "WooCommerce product IDs to price"
                  },
                  "regularPrices": {
                    "type": "object",
                    "additionalProperties": { "type": "number" },
                    "description": "Regular prices in USD keyed by product ID"
                  },
                  "zone": {
                    "type": "string",
                    "enum": ["local", "nationwide"],
                    "description": "Optional guest delivery zone"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Prices calculated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "prices": {
                      "type": "object",
                      "additionalProperties": {
                        "$ref": "#/components/schemas/PriceResult"
                      },
                      "description": "Price results keyed by product ID"
                    },
                    "userType": {
                      "type": "string",
                      "enum": ["member", "guest"]
                    },
                    "zone": {
                      "type": "string",
                      "enum": ["local", "nationwide"]
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/Error" },
          "429": { "$ref": "#/components/responses/Error" },
          "404": { "$ref": "#/components/responses/Error" }
        }
      }
    }
  },
  "components": {
    "responses": {
      "Error": {
        "description": "Error response using the standard JSON envelope",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ApiError" }
          }
        }
      }
    },
    "schemas": {
      "ApiError": {
        "type": "object",
        "description": "Standard error envelope returned by every API endpoint. Unmatched /api/* paths return this with code NOT_FOUND.",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["code", "message"],
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine code, SCREAMING_SNAKE (e.g. NOT_FOUND, MISSING_PARAMETER, RATE_LIMITED, INTERNAL_ERROR)"
              },
              "message": {
                "type": "string",
                "description": "Human-readable explanation"
              },
              "hint": {
                "type": "string",
                "description": "Optional resolution hint"
              }
            }
          }
        }
      },
      "Product": {
        "type": "object",
        "description": "Typesense product document. Key fields listed; additional catalog fields may be present.",
        "properties": {
          "product_id": {
            "type": "integer",
            "description": "WooCommerce product ID"
          },
          "product_name": { "type": "string" },
          "url_slug": {
            "type": "string",
            "description": "Product page: https://mysupplyclub.com/product/{url_slug}"
          },
          "brand_": { "type": "string" },
          "material_": { "type": "string" },
          "website_price": {
            "type": "number",
            "description": "Guest price in USD per case"
          },
          "unit_price": { "type": "number", "description": "USD per unit" },
          "case_configuration": { "type": "string" },
          "image_url": { "type": "string" }
        }
      },
      "PriceResult": {
        "type": "object",
        "properties": {
          "productId": { "type": "integer" },
          "regularPrice": { "type": "number", "description": "USD" },
          "price": { "type": "number", "description": "Calculated price, USD" },
          "savingsAmount": { "type": "number", "description": "USD saved" },
          "savingsPercent": { "type": "number", "description": "0-100" },
          "source": {
            "type": "string",
            "description": "Where the price came from (e.g. csp, fallback)"
          }
        }
      }
    }
  }
}
