{"openapi":"3.1.0","info":{"title":"Dubai Grocery Prices","version":"1.0.0","description":"Observed Dubai grocery prices, indicative online search, and published delivery rules. No API key. Limits: 60 requests/minute and 1500/day/IP per instance (at most 2 instances). Online search: 30 new/day across the API, 5/client/day, inside the existing global 80/day cap. Cache hits are free of search quotas. Attribution and browser links accompany results."},"servers":[{"url":"https://prices.brainy.ae"}],"externalDocs":{"url":"https://prices.brainy.ae/developers.html"},"paths":{"/api/v1":{"get":{"operationId":"api_info","responses":{"200":{"description":"API name, version and discovery URLs","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"version":{"type":"string","minLength":1,"maxLength":120},"docs":{"type":"string","minLength":1,"maxLength":300},"openapi":{"type":"string","minLength":1,"maxLength":300},"mcp":{"type":"string","minLength":1,"maxLength":300},"open_in_browser":{"type":"string","minLength":1,"maxLength":300},"attribution":{"type":"string","minLength":1,"maxLength":500}},"required":["name","version","docs","openapi","mcp","open_in_browser","attribution"],"additionalProperties":false}}}}}}},"/api/v1/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"description":"This OpenAPI 3.1 document","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/compare":{"post":{"operationId":"compare_grocery_list","summary":"Compare the total cost of a grocery list across Dubai supermarkets. Uses observed catalogue prices and published delivery rules; unknown delivery stays unknown. Product and quantity matches are explicit proposals. A single product is ranked by product price; minimum order is shown without excluding stores.","responses":{"200":{"description":"Success. All money is AED; unknown values are null.","content":{"application/json":{"schema":{"type":"object","properties":{"currency":{"const":"AED"},"observed_at":{"anyOf":[{"type":"string"},{"type":"null"}]},"stale":{"type":"boolean"},"attribution":{"type":"string"},"open_in_browser":{"type":"string","format":"uri"},"catalog_date":{"anyOf":[{"type":"string"},{"type":"null"}]},"single_product_mode":{"type":"boolean"},"outcome":{"type":"string","minLength":1,"maxLength":120},"confidence":{"type":"string","minLength":1,"maxLength":120},"area":{"type":"object","properties":{"ok":{"type":"boolean"},"reason":{"anyOf":[{"type":"string","minLength":1,"maxLength":120},{"type":"null"}]},"value":{"type":"string","maxLength":80}},"required":["ok","reason","value"],"additionalProperties":false},"recommended_store":{"anyOf":[{"type":"object","properties":{"retailerId":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","minLength":1,"maxLength":200},"subtotalAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"totalMinAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"totalMaxAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"feeMinAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"feeMaxAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"feeKnown":{"type":"boolean"},"shipReason":{"anyOf":[{"type":"string","minLength":1,"maxLength":120},{"type":"null"}]},"covered":{"type":"integer"},"of":{"type":"integer"}},"required":["retailerId","label","subtotalAed","feeKnown"],"additionalProperties":true},{"type":"null"}]},"ranking":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"retailerId":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","minLength":1,"maxLength":200},"subtotalAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"totalMinAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"totalMaxAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"feeMinAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"feeMaxAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"feeKnown":{"type":"boolean"},"shipReason":{"anyOf":[{"type":"string","minLength":1,"maxLength":120},{"type":"null"}]},"covered":{"type":"integer"},"of":{"type":"integer"}},"required":["retailerId","label","subtotalAed","feeKnown"],"additionalProperties":true},{"type":"null"}]},"description":"Stores priced on the same product set. In single-product mode every row also carries unit_price_aed, unit and the chosen offer (title, pack size, packs)."},"items":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":120},"status":{"enum":["compared","not_compared","unresolved"]},"match":{"anyOf":[{"type":"string","minLength":1,"maxLength":120},{"type":"null"}]},"product":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"name":{"type":"string","minLength":1,"maxLength":200},"comparison":{"enum":["exact","equivalent"]},"unit":{"enum":["each","kg","l"]}},"required":["id","name","comparison","unit"],"additionalProperties":false},{"type":"null"}]},"quantity":{"anyOf":[{"type":"object","properties":{"value":{"type":"number"},"unit":{"enum":["each","kg","l"]},"source":{"type":"string","minLength":1,"maxLength":120},"assumed":{"type":"boolean"}},"required":["value","unit","source","assumed"],"additionalProperties":false},{"type":"null"}]},"at_recommended_store":{"anyOf":[{"type":"object","properties":{"store_id":{"type":"string","minLength":1,"maxLength":80},"store":{"type":"string","minLength":1,"maxLength":200},"title":{"type":"string","minLength":1,"maxLength":300},"pack_quantity":{"type":"number","description":"Size of ONE pack in `unit` (e.g. 0.2 kg). Explicit even when the store title omits it."},"unit":{"enum":["each","kg","l"]},"packs":{"anyOf":[{"type":"integer"},{"type":"null"}]},"sale_mode":{"enum":["pack","weight"]},"price_aed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"cost_aed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"purchased_quantity":{"type":"number"},"unit_price_aed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"estimated":{"type":"boolean"},"observed_at":{"type":"string","minLength":1,"maxLength":120},"url":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]}},"required":["store_id","store","title","pack_quantity","unit","packs","sale_mode","price_aed","cost_aed","purchased_quantity","unit_price_aed","estimated","observed_at","url"],"additionalProperties":false},{"type":"null"}]},"cheapest_seen":{"anyOf":[{"type":"object","properties":{"store_id":{"type":"string","minLength":1,"maxLength":80},"store":{"type":"string","minLength":1,"maxLength":200},"cost_aed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]}},"required":["store_id","store","cost_aed"],"additionalProperties":false},{"type":"null"}]},"unresolved_reason":{"anyOf":[{"type":"string","minLength":1,"maxLength":120},{"type":"null"}]},"candidates":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"name":{"type":"string","minLength":1,"maxLength":200}},"required":["id","name"],"additionalProperties":false}},"next_step":{"anyOf":[{"type":"string","minLength":1,"maxLength":300},{"type":"null"}]}},"required":["text","status","match","product","quantity","at_recommended_store","cheapest_seen","unresolved_reason","candidates","next_step"],"additionalProperties":false},"description":"One entry per requested item, in request order: chosen product and quantity, pack and price at the recommended store, or why it is unresolved and what to try next."},"compared":{"type":"array","items":{"type":"object"}},"not_compared":{"type":"array","items":{"type":"object"}},"not_found":{"type":"array","items":{"type":"object"}},"below_minimum_stores":{"type":"array","items":{"type":"object"}},"advice":{"type":"object","description":"Site advisor export: monetary field suffix Fils replaced with Aed and divided by 100. Contains explicit assumptions, coverage, provisional outcomes and shipping uncertainty."},"browser_handoff_truncated":{"type":"boolean","description":"The website can preload up to 4000 characters; true if the supplied list exceeds that limit."}},"required":["currency","observed_at","stale","attribution","open_in_browser","catalog_date","single_product_mode","outcome","confidence","area","recommended_store","ranking","items","compared","not_compared","not_found","below_minimum_stores","advice","browser_handoff_truncated"],"additionalProperties":false}}}},"400":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"404":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"405":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"413":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"422":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded. Retry-After gives seconds to wait.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"503":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","minItems":1,"maxItems":40,"items":{"type":"string","minLength":1,"maxLength":120}},"area":{"type":"string","maxLength":80}},"required":["items"],"additionalProperties":false}}}}},"get":{"operationId":"compare_grocery_list_get","summary":"Compare the total cost of a grocery list across Dubai supermarkets. Uses observed catalogue prices and published delivery rules; unknown delivery stays unknown. Product and quantity matches are explicit proposals. A single product is ranked by product price; minimum order is shown without excluding stores.","parameters":[{"name":"items","in":"query","required":true,"schema":{"type":"string","description":"Comma-separated list, 1–40 items of at most 120 characters each."}},{"name":"area","in":"query","required":false,"schema":{"type":"string","maxLength":80}}],"responses":{"200":{"description":"Success. All money is AED; unknown values are null.","content":{"application/json":{"schema":{"type":"object","properties":{"currency":{"const":"AED"},"observed_at":{"anyOf":[{"type":"string"},{"type":"null"}]},"stale":{"type":"boolean"},"attribution":{"type":"string"},"open_in_browser":{"type":"string","format":"uri"},"catalog_date":{"anyOf":[{"type":"string"},{"type":"null"}]},"single_product_mode":{"type":"boolean"},"outcome":{"type":"string","minLength":1,"maxLength":120},"confidence":{"type":"string","minLength":1,"maxLength":120},"area":{"type":"object","properties":{"ok":{"type":"boolean"},"reason":{"anyOf":[{"type":"string","minLength":1,"maxLength":120},{"type":"null"}]},"value":{"type":"string","maxLength":80}},"required":["ok","reason","value"],"additionalProperties":false},"recommended_store":{"anyOf":[{"type":"object","properties":{"retailerId":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","minLength":1,"maxLength":200},"subtotalAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"totalMinAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"totalMaxAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"feeMinAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"feeMaxAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"feeKnown":{"type":"boolean"},"shipReason":{"anyOf":[{"type":"string","minLength":1,"maxLength":120},{"type":"null"}]},"covered":{"type":"integer"},"of":{"type":"integer"}},"required":["retailerId","label","subtotalAed","feeKnown"],"additionalProperties":true},{"type":"null"}]},"ranking":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"retailerId":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","minLength":1,"maxLength":200},"subtotalAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"totalMinAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"totalMaxAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"feeMinAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"feeMaxAed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"feeKnown":{"type":"boolean"},"shipReason":{"anyOf":[{"type":"string","minLength":1,"maxLength":120},{"type":"null"}]},"covered":{"type":"integer"},"of":{"type":"integer"}},"required":["retailerId","label","subtotalAed","feeKnown"],"additionalProperties":true},{"type":"null"}]},"description":"Stores priced on the same product set. In single-product mode every row also carries unit_price_aed, unit and the chosen offer (title, pack size, packs)."},"items":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":120},"status":{"enum":["compared","not_compared","unresolved"]},"match":{"anyOf":[{"type":"string","minLength":1,"maxLength":120},{"type":"null"}]},"product":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"name":{"type":"string","minLength":1,"maxLength":200},"comparison":{"enum":["exact","equivalent"]},"unit":{"enum":["each","kg","l"]}},"required":["id","name","comparison","unit"],"additionalProperties":false},{"type":"null"}]},"quantity":{"anyOf":[{"type":"object","properties":{"value":{"type":"number"},"unit":{"enum":["each","kg","l"]},"source":{"type":"string","minLength":1,"maxLength":120},"assumed":{"type":"boolean"}},"required":["value","unit","source","assumed"],"additionalProperties":false},{"type":"null"}]},"at_recommended_store":{"anyOf":[{"type":"object","properties":{"store_id":{"type":"string","minLength":1,"maxLength":80},"store":{"type":"string","minLength":1,"maxLength":200},"title":{"type":"string","minLength":1,"maxLength":300},"pack_quantity":{"type":"number","description":"Size of ONE pack in `unit` (e.g. 0.2 kg). Explicit even when the store title omits it."},"unit":{"enum":["each","kg","l"]},"packs":{"anyOf":[{"type":"integer"},{"type":"null"}]},"sale_mode":{"enum":["pack","weight"]},"price_aed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"cost_aed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"purchased_quantity":{"type":"number"},"unit_price_aed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"estimated":{"type":"boolean"},"observed_at":{"type":"string","minLength":1,"maxLength":120},"url":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]}},"required":["store_id","store","title","pack_quantity","unit","packs","sale_mode","price_aed","cost_aed","purchased_quantity","unit_price_aed","estimated","observed_at","url"],"additionalProperties":false},{"type":"null"}]},"cheapest_seen":{"anyOf":[{"type":"object","properties":{"store_id":{"type":"string","minLength":1,"maxLength":80},"store":{"type":"string","minLength":1,"maxLength":200},"cost_aed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]}},"required":["store_id","store","cost_aed"],"additionalProperties":false},{"type":"null"}]},"unresolved_reason":{"anyOf":[{"type":"string","minLength":1,"maxLength":120},{"type":"null"}]},"candidates":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"name":{"type":"string","minLength":1,"maxLength":200}},"required":["id","name"],"additionalProperties":false}},"next_step":{"anyOf":[{"type":"string","minLength":1,"maxLength":300},{"type":"null"}]}},"required":["text","status","match","product","quantity","at_recommended_store","cheapest_seen","unresolved_reason","candidates","next_step"],"additionalProperties":false},"description":"One entry per requested item, in request order: chosen product and quantity, pack and price at the recommended store, or why it is unresolved and what to try next."},"compared":{"type":"array","items":{"type":"object"}},"not_compared":{"type":"array","items":{"type":"object"}},"not_found":{"type":"array","items":{"type":"object"}},"below_minimum_stores":{"type":"array","items":{"type":"object"}},"advice":{"type":"object","description":"Site advisor export: monetary field suffix Fils replaced with Aed and divided by 100. Contains explicit assumptions, coverage, provisional outcomes and shipping uncertainty."},"browser_handoff_truncated":{"type":"boolean","description":"The website can preload up to 4000 characters; true if the supplied list exceeds that limit."}},"required":["currency","observed_at","stale","attribution","open_in_browser","catalog_date","single_product_mode","outcome","confidence","area","recommended_store","ranking","items","compared","not_compared","not_found","below_minimum_stores","advice","browser_handoff_truncated"],"additionalProperties":false}}}},"400":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"404":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"405":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"413":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"422":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded. Retry-After gives seconds to wait.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"503":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}}}}},"/api/v1/products":{"get":{"operationId":"search_products","summary":"Search the observed Dubai grocery catalogue by name, brand or identifier. Returns exact/equivalent matches and dated offers in AED. This does not run a live web search.","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":120}}],"responses":{"200":{"description":"Success. All money is AED; unknown values are null.","content":{"application/json":{"schema":{"type":"object","properties":{"currency":{"const":"AED"},"observed_at":{"anyOf":[{"type":"string"},{"type":"null"}]},"stale":{"type":"boolean"},"attribution":{"type":"string"},"open_in_browser":{"type":"string","format":"uri"},"query":{"type":"string","minLength":1,"maxLength":120},"count":{"type":"integer"},"products":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"name":{"type":"string","minLength":1,"maxLength":200},"unit":{"enum":["each","kg","l"]},"size":{"type":"object","properties":{"quantity":{"anyOf":[{"type":"number"},{"type":"null"}]},"unit":{"type":"string","minLength":1,"maxLength":120}},"required":["quantity","unit"],"additionalProperties":false},"comparison":{"enum":["exact","equivalent"]},"page":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"open_in_browser":{"type":"string","format":"uri"},"offers":{"type":"array","items":{"type":"object","properties":{"store_id":{"type":"string","minLength":1,"maxLength":80},"store":{"type":"string","minLength":1,"maxLength":200},"title":{"type":"string","minLength":1,"maxLength":300},"price_aed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"unit_price_aed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"unit":{"type":"string","minLength":1,"maxLength":120},"pack_quantity":{"type":"number"},"sale_mode":{"enum":["pack","weight"]},"url":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"observed_at":{"type":"string","minLength":1,"maxLength":120},"comparison":{"enum":["exact","equivalent"]},"status":{"type":"string","minLength":1,"maxLength":120},"available":{"type":"boolean"}},"required":["store_id","store","title","price_aed","unit_price_aed","unit","pack_quantity","sale_mode","url","observed_at","comparison","status","available"],"additionalProperties":false}}},"required":["id","name","unit","size","comparison","page","open_in_browser","offers"],"additionalProperties":false}}},"required":["currency","observed_at","stale","attribution","open_in_browser","query","count","products"],"additionalProperties":false}}}},"400":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"404":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"405":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"413":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"422":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded. Retry-After gives seconds to wait.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"503":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}}}}},"/api/v1/products/{id}":{"get":{"operationId":"get_product","summary":"Get a catalogue product, observed store offers and product history where available. Basket-total history is never presented as product history.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":80}}],"responses":{"200":{"description":"Success. All money is AED; unknown values are null.","content":{"application/json":{"schema":{"type":"object","properties":{"currency":{"const":"AED"},"observed_at":{"anyOf":[{"type":"string"},{"type":"null"}]},"stale":{"type":"boolean"},"attribution":{"type":"string"},"open_in_browser":{"type":"string","format":"uri"},"product":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"name":{"type":"string","minLength":1,"maxLength":200},"unit":{"enum":["each","kg","l"]},"size":{"type":"object","properties":{"quantity":{"anyOf":[{"type":"number"},{"type":"null"}]},"unit":{"type":"string","minLength":1,"maxLength":120}},"required":["quantity","unit"],"additionalProperties":false},"comparison":{"enum":["exact","equivalent"]},"page":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"open_in_browser":{"type":"string","format":"uri"},"offers":{"type":"array","items":{"type":"object","properties":{"store_id":{"type":"string","minLength":1,"maxLength":80},"store":{"type":"string","minLength":1,"maxLength":200},"title":{"type":"string","minLength":1,"maxLength":300},"price_aed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"unit_price_aed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"unit":{"type":"string","minLength":1,"maxLength":120},"pack_quantity":{"type":"number"},"sale_mode":{"enum":["pack","weight"]},"url":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"observed_at":{"type":"string","minLength":1,"maxLength":120},"comparison":{"enum":["exact","equivalent"]},"status":{"type":"string","minLength":1,"maxLength":120},"available":{"type":"boolean"}},"required":["store_id","store","title","price_aed","unit_price_aed","unit","pack_quantity","sale_mode","url","observed_at","comparison","status","available"],"additionalProperties":false}}},"required":["id","name","unit","size","comparison","page","open_in_browser","offers"],"additionalProperties":false},"history":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","minLength":1,"maxLength":120},"price_aed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"store":{"anyOf":[{"type":"string","minLength":1,"maxLength":120},{"type":"null"}]}},"required":["date","price_aed","store"],"additionalProperties":false}},"history_note":{"type":"string","minLength":1,"maxLength":500}},"required":["currency","observed_at","stale","attribution","open_in_browser","product","history","history_note"],"additionalProperties":false}}}},"400":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"404":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"405":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"413":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"422":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded. Retry-After gives seconds to wait.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"503":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}}}}},"/api/v1/stores":{"get":{"operationId":"list_stores","summary":"List Dubai stores and their published delivery rules, minimum orders, source URLs and verification dates. Unknown or expired delivery rules are explicitly labelled.","responses":{"200":{"description":"Success. All money is AED; unknown values are null.","content":{"application/json":{"schema":{"type":"object","properties":{"currency":{"const":"AED"},"observed_at":{"anyOf":[{"type":"string"},{"type":"null"}]},"stale":{"type":"boolean"},"attribution":{"type":"string"},"open_in_browser":{"type":"string","format":"uri"},"stores":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":80},"name":{"type":"string","minLength":1,"maxLength":200},"url":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"kind":{"anyOf":[{"type":"string","minLength":1,"maxLength":120},{"type":"null"}]},"integrated":{"type":"boolean"},"coverage_note":{"type":"string"},"minimum_order_aed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"minimum_source":{"anyOf":[{"type":"string"},{"type":"null"}]},"policy_status":{"type":"string","minLength":1,"maxLength":120},"policy_reason":{"anyOf":[{"type":"string","minLength":1,"maxLength":120},{"type":"null"}]},"shipping_rule":{"anyOf":[{"type":"object","description":"Published rule with monetary fields in AED (suffix Aed); null means unknown."},{"type":"null"}]},"source":{"anyOf":[{"type":"string"},{"type":"null"}]},"checked_at":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","name","url","kind","integrated","coverage_note","minimum_order_aed","minimum_source","policy_status","policy_reason","shipping_rule","source","checked_at"],"additionalProperties":false}}},"required":["currency","observed_at","stale","attribution","open_in_browser","stores"],"additionalProperties":false}}}},"400":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"404":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"405":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"413":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"422":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded. Retry-After gives seconds to wait.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"503":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}}}}},"/api/v1/search":{"get":{"operationId":"find_price_online","summary":"Find indicative online prices from Google Shopping UAE. New searches have strict daily limits. If queued, wait retry_after_s before calling again. Delivery is excluded; check product variants, stock and final price at the store.","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":200}}],"responses":{"200":{"description":"Success. All money is AED; unknown values are null.","content":{"application/json":{"schema":{"type":"object","properties":{"currency":{"const":"AED"},"observed_at":{"anyOf":[{"type":"string"},{"type":"null"}]},"stale":{"type":"boolean"},"attribution":{"type":"string"},"open_in_browser":{"type":"string","format":"uri"},"query":{"type":"string","minLength":1,"maxLength":200},"state":{"enum":["ready","queued","rejected","capped"]},"results":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":300},"merchant":{"type":"string","minLength":1,"maxLength":120},"price_aed":{"anyOf":[{"type":"number","multipleOf":0.01,"description":"AED, rounded to two decimal places. Unknown amounts are null."},{"type":"null"}]},"url":{"type":"string","format":"uri"},"relevance":{"type":"number","minimum":0,"maximum":1}},"required":["title","merchant","price_aed","url","relevance"],"additionalProperties":false}},"retry_after_s":{"type":"number","minimum":0},"cached_at":{"anyOf":[{"type":"string"},{"type":"null"}]},"shipping":{"type":"null"},"note":{"type":"string","minLength":1,"maxLength":500},"error":{"type":"object","properties":{"code":{"type":"string","minLength":1,"maxLength":120},"message":{"type":"string","minLength":1,"maxLength":1000}},"required":["code","message"],"additionalProperties":false}},"required":["currency","observed_at","stale","attribution","open_in_browser","query","state","results","retry_after_s","cached_at","shipping","note"],"additionalProperties":false}}}},"400":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"404":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"405":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"413":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"422":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded. Retry-After gives seconds to wait.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}},"503":{"description":"Request failed.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"open_in_browser":{"type":"string"},"attribution":{"type":"string"}},"required":["error","open_in_browser","attribution"],"additionalProperties":false}}}}}}}}}