{
  "openapi": "3.1.0",
  "info": {
    "title": "Sonpetit Public Catalogue API",
    "version": "1.0.0",
    "description": "Read-only API for discovering public Sonpetit products and categories. Checkout, customer accounts, orders and administrative operations are intentionally excluded."
  },
  "servers": [{"url": "https://sonpetit.com"}],
  "tags": [{"name":"Catalogue","description":"Public read-only Sonpetit catalogue operations."}],
  "paths": {
    "/api/public/v1/products": {
      "get": {
        "tags":["Catalogue"],
        "operationId":"searchPublicProducts",
        "summary":"Search public products",
        "description":"Returns published, publicly visible Sonpetit products. No authentication is required.",
        "parameters":[
          {"name":"query","in":"query","description":"Optional text matched against product name, SKU or product key.","schema":{"type":"string","maxLength":120}},
          {"name":"lang","in":"query","description":"Response language.","schema":{"type":"string","enum":["es","ca","en","fr","de","zh","ko","tl"],"default":"es"}},
          {"name":"limit","in":"query","description":"Maximum products to return.","schema":{"type":"integer","minimum":1,"maximum":50,"default":20}},
          {"name":"offset","in":"query","description":"Number of products to skip.","schema":{"type":"integer","minimum":0,"default":0}}
        ],
        "responses": {
          "200":{"description":"Product list.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListResponse"}}}},
          "429":{"$ref":"#/components/responses/RateLimited"},
          "503":{"$ref":"#/components/responses/ServiceUnavailable"}
        }
      }
    },
    "/api/public/v1/products/{id}": {
      "get": {
        "tags":["Catalogue"],
        "operationId":"getPublicProduct",
        "summary":"Get one public product",
        "description":"Returns one public product by translated slug, SKU or stable product key.",
        "parameters":[
          {"name":"id","in":"path","required":true,"description":"Product slug, SKU or product key.","schema":{"type":"string","minLength":1,"maxLength":190}},
          {"name":"lang","in":"query","description":"Response language.","schema":{"type":"string","enum":["es","ca","en","fr","de","zh","ko","tl"],"default":"es"}}
        ],
        "responses": {
          "200":{"description":"Product details.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/Product"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},
          "404":{"$ref":"#/components/responses/NotFound"},
          "429":{"$ref":"#/components/responses/RateLimited"},
          "503":{"$ref":"#/components/responses/ServiceUnavailable"}
        }
      }
    },
    "/api/public/v1/categories": {
      "get": {
        "tags":["Catalogue"],
        "operationId":"listPublicCategories",
        "summary":"List public categories",
        "description":"Lists active public categories that currently contain public products.",
        "parameters":[{"name":"lang","in":"query","description":"Response language.","schema":{"type":"string","enum":["es","ca","en","fr","de","zh","ko","tl"],"default":"es"}}],
        "responses": {
          "200":{"description":"Category list.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Category"}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},
          "429":{"$ref":"#/components/responses/RateLimited"},
          "503":{"$ref":"#/components/responses/ServiceUnavailable"}
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Product": {"type":"object","required":["id","productKey","sku","type","name","slug","url","price","currency","availability"],"properties":{"id":{"type":"integer"},"productKey":{"type":"string"},"sku":{"type":"string"},"type":{"type":"string","enum":["simple","variable","grouped","pack"]},"name":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string","format":"uri"},"description":{"type":"string"},"price":{"type":"number","format":"double"},"regularPrice":{"type":"number","format":"double"},"salePrice":{"type":["number","null"],"format":"double"},"currency":{"type":"string","const":"EUR"},"availability":{"type":"string","enum":["in_stock","out_of_stock"]},"image":{"type":["string","null"],"format":"uri"}}},
      "Category": {"type":"object","required":["id","parentId","key","name","slug","productCount"],"properties":{"id":{"type":"integer"},"parentId":{"type":"integer"},"key":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"productCount":{"type":"integer","minimum":1}}},
      "Meta": {"type":"object","properties":{"language":{"type":"string"},"limit":{"type":"integer"},"offset":{"type":"integer"},"count":{"type":"integer"}}},
      "ProductListResponse": {"type":"object","required":["data","meta","links"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Product"}},"meta":{"$ref":"#/components/schemas/Meta"},"links":{"type":"object","additionalProperties":{"type":"string","format":"uri"}}}},
      "Error": {"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","resolution"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"resolution":{"type":"string"},"details":{"type":"object","additionalProperties":true}}}}}
    },
    "responses": {
      "NotFound":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},
      "RateLimited":{"description":"Rate limit exceeded.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},
      "ServiceUnavailable":{"description":"Catalogue backend temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}
    }
  }
}
