{"openapi":"3.1.0","info":{"title":"LeafStock public catalog API","version":"1.0.0","description":"Read-only Northeast Ohio recreational dispensary snapshots. No signup or API key is required. Prices are USD cents; verify observation timestamps, eligibility, stock, and final pricing with the source dispensary. This contract documents selected existing public endpoints; account APIs are excluded."},"servers":[{"url":"https://migration.leafstock.app"}],"externalDocs":{"url":"https://migration.leafstock.app/agents"},"security":[],"paths":{"/api/search":{"post":{"operationId":"searchCatalog","summary":"Search catalog text; product identities currently cover vapes only","description":"Mixed brand, strain, category, and listing matches are also returned. For non-vape offers/history, obtain a canonical product link from the catalog or sitemap.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["query"],"properties":{"query":{"type":"string","minLength":1,"maxLength":120,"description":"Nonblank search text, e.g. Blue Dream."},"limit":{"type":"integer","minimum":1,"maximum":48,"default":24}}},"example":{"query":"Blue Dream","limit":5}}}},"responses":{"200":{"description":"Public catalog snapshot. Not a guarantee of price or stock; preserve freshness information.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResult"}}}},"400":{"description":"Request rejected or catalog unavailable. Error details never include SQL or credentials.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Request rejected or catalog unavailable. Error details never include SQL or credentials.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/products/{category}/{productSlug}/offers":{"get":{"operationId":"getProductOffers","summary":"Read store offers and snapshot freshness for a canonical product","parameters":[{"name":"category","in":"path","required":true,"schema":{"type":"string","enum":["flower","vapes","edibles","pre-rolls","concentrates","tinctures","topicals"]}},{"name":"productSlug","in":"path","required":true,"description":"Use the slug from a canonical /products/{category}/{productSlug} link. Not every search hit is a product.","schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Public catalog snapshot. Not a guarantee of price or stock; preserve freshness information.","content":{"application/json":{"schema":{"type":"object","required":["availability"],"properties":{"categoryKey":{"type":"string"},"productSlug":{"type":"string"},"availability":{"type":"array","items":{"type":"object","additionalProperties":true}},"offersFreshness":{"type":["object","null"],"additionalProperties":true}}}}}},"404":{"description":"Request rejected or catalog unavailable. Error details never include SQL or credentials.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Request rejected or catalog unavailable. Error details never include SQL or credentials.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/products/{category}/{productSlug}/history":{"get":{"operationId":"getProductHistory","summary":"Read observed price and availability history","parameters":[{"name":"category","in":"path","required":true,"schema":{"type":"string","enum":["flower","vapes","edibles","pre-rolls","concentrates","tinctures","topicals"]}},{"name":"productSlug","in":"path","required":true,"description":"Use the slug from a canonical /products/{category}/{productSlug} link. Not every search hit is a product.","schema":{"type":"string","minLength":1}},{"name":"days","in":"query","schema":{"type":"integer","minimum":1,"maximum":365,"default":30}}],"responses":{"200":{"description":"Public catalog snapshot. Not a guarantee of price or stock; preserve freshness information.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"Historical observations with coverage and windowDays; sparse history must not be presented as continuous availability."}}}},"404":{"description":"Request rejected or catalog unavailable. Error details never include SQL or credentials.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Request rejected or catalog unavailable. Error details never include SQL or credentials.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"}}}}},"SearchResult":{"type":"object","required":["query","hits","total","empty","parsedText"],"properties":{"query":{"type":"string"},"parsedText":{"type":"string"},"total":{"type":"integer"},"empty":{"type":"boolean"},"priceMaxCents":{"type":["integer","null"]},"hits":{"type":"array","maxItems":48,"items":{"type":"object","required":["kind","id","label","href","matchQuality"],"properties":{"kind":{"type":"string","enum":["brand","product","strain","type","listing"]},"id":{"type":"string"},"label":{"type":"string"},"href":{"type":"string","description":"Canonical relative page link; resolve against the API server origin."},"matchQuality":{"type":"string","enum":["exact","prefix","tokens","contains","listing"]},"categoryKey":{"type":["string","null"]},"minPriceCents":{"type":["integer","null"]},"maxPriceCents":{"type":["integer","null"]}}}}}}}}}