---
title: "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. Generic estimates are labelled and totalled separately; store order uses observed common products only."
method: POST
path: "/api/v1/compare"
---

# 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. Generic estimates are labelled and totalled separately; store order uses observed common products only.

`POST /api/v1/compare`

## Request

- Base URL: `https://prices.brainy.ae`
- URL: `https://prices.brainy.ae/api/v1/compare`
- Auth: none declared

## Request body

- object
  - `items` string[], required
  - `area` string

## Response `200`

Success. All money is AED; unknown values are null.

- object
  - `currency` 'AED', required
  - `observed_at` string, nullable, required
  - `stale` boolean, required
  - `attribution` string, required
  - `open_in_browser` string, uri, required
  - `catalog_date` string, nullable, required
  - `single_product_mode` boolean, required
  - `outcome` string, required: 'single-store' when only one online store has prices for the list: no store ranking (we only compare stores that allow collecting their prices or have given us permission).
  - `confidence` string, required
  - `area` object, required
    - `ok` boolean, required
    - `reason` string, nullable, required
    - `value` string, required
  - `recommended_store` object, nullable, required: With outcome 'single-store' this is the only store with prices, not a recommendation.
    - `retailerId` string, required
    - `label` string, required
    - `subtotalAed` number, nullable, required: AED, rounded to two decimal places. Unknown amounts are null.
    - `totalMinAed` number, nullable: AED, rounded to two decimal places. Unknown amounts are null.
    - `totalMaxAed` number, nullable: AED, rounded to two decimal places. Unknown amounts are null.
    - `feeMinAed` number, nullable: AED, rounded to two decimal places. Unknown amounts are null.
    - `feeMaxAed` number, nullable: AED, rounded to two decimal places. Unknown amounts are null.
    - `feeKnown` boolean, required
    - `shipReason` string, nullable
    - `covered` integer
    - `of` integer
    - `totals` object
      - `observed_aed` number, required
      - `estimated_aed` object, required
        - `value_aed` number, required
        - `low_aed` number, required
        - `high_aed` number, required
      - `items_observed` integer, required
      - `items_estimated` integer, required
      - `items_unknown` integer, required
    - `estimated_label` 'items not priced at this store — estimated generic price'
    - `cart` object
      - `method` 'links', required
      - `add_all_url` unknown, required
      - `items` object[], required
        - `text` string, required
        - `url` string, uri, required
        - `packs` number, nullable, required
  - `ranking` object[], required: 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).
    - `retailerId` string, required
    - `label` string, required
    - `subtotalAed` number, nullable, required: AED, rounded to two decimal places. Unknown amounts are null.
    - `totalMinAed` number, nullable: AED, rounded to two decimal places. Unknown amounts are null.
    - `totalMaxAed` number, nullable: AED, rounded to two decimal places. Unknown amounts are null.
    - `feeMinAed` number, nullable: AED, rounded to two decimal places. Unknown amounts are null.
    - `feeMaxAed` number, nullable: AED, rounded to two decimal places. Unknown amounts are null.
    - `feeKnown` boolean, required
    - `shipReason` string, nullable
    - `covered` integer
    - `of` integer
    - `totals` object
      - `observed_aed` number, required
      - `estimated_aed` object, required
        - `value_aed` number, required
        - `low_aed` number, required
        - `high_aed` number, required
      - `items_observed` integer, required
      - `items_estimated` integer, required
      - `items_unknown` integer, required
    - `estimated_label` 'items not priced at this store — estimated generic price'
    - `cart` object
      - `method` 'links', required
      - `add_all_url` unknown, required
      - `items` object[], required
        - `text` string, required
        - `url` string, uri, required
        - `packs` number, nullable, required
  - `items` object[], required: 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.
    - `text` string, required
    - `status` 'compared' | 'not_compared' | 'unresolved', required
    - `match` string, nullable, required
    - `product` object, nullable, required
      - `id` string, required
      - `name` string, required
      - `comparison` 'exact' | 'equivalent', required
      - `unit` 'each' | 'kg' | 'l', required
    - `quantity` object, nullable, required
      - `value` number, required
      - `unit` 'each' | 'kg' | 'l', required
      - `source` string, required
      - `assumed` boolean, required
    - `at_recommended_store` object, nullable, required
      - `store_id` string, required
      - `store` string, required
      - `title` string, required
      - `pack_quantity` number, required: Size of ONE pack in `unit` (e.g. 0.2 kg). Explicit even when the store title omits it.
      - `unit` 'each' | 'kg' | 'l', required
      - `packs` integer, nullable, required
      - `sale_mode` 'pack' | 'weight', required
      - `price_aed` number, nullable, required: AED, rounded to two decimal places. Unknown amounts are null.
      - `cost_aed` number, nullable, required: AED, rounded to two decimal places. Unknown amounts are null.
      - `purchased_quantity` number, required
      - `unit_price_aed` number, nullable, required: AED, rounded to two decimal places. Unknown amounts are null.
      - `estimated` boolean, required
      - `observed_at` string, required
      - `url` string, uri, nullable, required
    - `cheapest_seen` object, nullable, required
      - `store_id` string, required
      - `store` string, required
      - `cost_aed` number, nullable, required: AED, rounded to two decimal places. Unknown amounts are null.
    - `unresolved_reason` string, nullable, required
    - `candidates` object[], required
      - `id` string, required
      - `name` string, required
    - `next_step` string, nullable, required
    - `estimate` object
      - `kind` 'estimate', required
      - `value_aed` number, required
      - `range_aed` object, required
        - `low_aed` number, required
        - `high_aed` number, required
      - `method` 'official_same_product' | 'own_last_observed' | 'official_category' | 'category_median' | 'shopper_reports', required
      - `basis` object, required
        - `source_ids` string[], required
        - `product_match` 'same_product' | 'same_category', required
        - `observations` integer, required
        - `observed_from` string, date, required
        - `observed_to` string, date, required
        - `note` string, nullable, required
        - `sources` object[], required
          - `source_id` string, required
          - `name` string, required
          - `url` string, uri, nullable, required
      - `confidence` 'high' | 'medium' | 'low', required
      - `as_of` string, date, required
      - `label` 'Estimate — not a store price', required
      - `unit` 'kg' | 'l' | 'each': Estimate per 1 catalogue unit; each is one item or catalogue pack.
      - `packs` number, nullable, required
      - `unit_value_aed` number, required
    - `price` unknown
  - `compared` object[], required
  - `not_compared` object[], required
  - `not_found` object[], required
  - `below_minimum_stores` object[], required
  - `advice` object, required: 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` boolean, required: The website can preload up to 4000 characters; true if the supplied list exceeds that limit.
  - `totals` object
    - `observed_aed` number, required
    - `estimated_aed` object, required
      - `value_aed` number, required
      - `low_aed` number, required
      - `high_aed` number, required
    - `items_observed` integer, required
    - `items_estimated` integer, required
    - `items_unknown` integer, required

## Other responses

- `400`: Request failed.
- `404`: Request failed.
- `405`: Request failed.
- `413`: Request failed.
- `422`: Request failed.
- `429`: Rate limit exceeded. Retry-After gives seconds to wait.
- `503`: Request failed.

---

[API](https://skmtc.dev/brainy/apis/dubai-cost-of-living-brainy-prices.md) · [All operations](https://skmtc.dev/brainy/apis/dubai-cost-of-living-brainy-prices/llms.txt) · [OpenAPI document](https://skmtc.dev/brainy/apis/dubai-cost-of-living-brainy-prices/revisions/a548a841d58c?raw)
