WEM Price Compare
Server Details
Price comparison across partner retailers. Read-only, 90-day history, disclosed affiliate.
- Status
- Healthy
- Uptime
- 100.0% over 58 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-06-18
- URL
TDQS
Scored across 11 tools
Several tools return product, offer, or price information (search_products, semantic_search, lookup_products, get_product, compare_offers, find_lowest_price), so boundaries can blur despite detailed descriptions. The distinctions are usually explained, but an agent may still misselect for tasks like 'get offers for product X' or 'find a product'.
Tool names use snake_case consistently and mostly follow a verb_noun pattern (compare_offers, get_product, search_products). Exceptions like semantic_search and find_lowest_price slightly break the pattern but remain readable.
11 tools are well-scoped for a price-comparison server, covering search, lookup, comparison, verification, evidence, categories, and promotions without excessive bloat.
The surface covers the core price-comparison lifecycle: search/lookup, product details, offer comparison, lowest-price selection, price verification, and evidence receipts. Minor gaps exist, such as no full historical price series or direct category browsing beyond examples, but agents can work around them.
Available Tools
11 toolscompare_offersCompare retailer offers for one productRead-onlyInspect
Lists the retailer offers WEM's catalogue holds for one product, current prices first and each group cheapest first, with WEM's 90-day price low (null when the product is held only in another currency). The product is found by barcode, catalogue slug or wem3.ai/pl/ URL, WEM ID, or a title (a model name, ASIN, MPN or merchant SKU) that must pass a relevance check; there is no live retailer search. A barcode, slug or WEM ID match is the product itself; a title match is inferred and marked so in identity. A marketplace offer priced far below the product's other offers is withheld and counted in filtered. When WEM does not hold the product, found is false and nextTool names search_products with a query.
| Name | Required | Description | Default |
|---|---|---|---|
| gtin | No | Product barcode: EAN-13, UPC-A, EAN-8 or GTIN-14. The strongest identifier. | |
| slug | No | WEM catalogue slug, or a wem3.ai/pl/{slug} URL / host path. Hosts may pass either form. | |
| title | No | Product or model name, or an ASIN, MPN or merchant SKU (e.g. AF400UK). The weakest identifier: used only when no barcode, slug or WEM ID is given, and only if it passes a relevance check; otherwise `found` is false rather than a guess. | |
| wem_id | No | WEM ID (W + 10 Crockford characters + check). Active catalogue products only. | |
| currency | No | ISO 4217 code for the shopper's market. Default GBP. Decides which market's offers WEM returns from its catalogue, not just how the answer reads ; WEM does not infer the market from IP. When WEM holds the product only in another currency it says so rather than presenting a foreign listing as the answer. |
Output Schema
| Name | Required | Description |
|---|---|---|
| next | No | Present when WEM's set of offers is thin. chrome_extension is a page that compares the same product on any retailer page, including shops without an affiliate programme. |
| found | Yes | False when the product is not in WEM’s catalogue. The rest of the fields below are then absent ; that does not mean the product is unavailable or unpriced. `unavailable` distinguishes an outage from a miss. `nextTool`, when present, names the next lookup. |
| links | No | The links from `offers`, cheapest first, pre-formatted. Each opens the retailer’s page for the offer WEM priced; a retailer URL found elsewhere may be a different listing or price. The same links are in this array and, when a host renders one, in the card. |
| offers | No | Current prices first (`priceStatus`), each group ascending by price; a stale or undated row is listed, never compared. Barcode, slug and WEM ID rows are the product. A title match is inferred; `identity.strength` says which. |
| reason | No | Present only when `found` is false: which identifier missed, and why. When `unavailable` is true this describes the outage rather than a missing product ; it is the reason the lookup failed, not a fact about the product. |
| search | No | Present when this result names no offer. `url` is WEM's results page for the query and `markdown` is the same link, pre-formatted. This tool reads the catalogue only, so an empty result here is not evidence the product is unavailable or unpriced. |
| source | No | |
| product | No | |
| ranking | No | Why the offers are in this order. Offers are ordered by price, lowest first; affiliate commission is not an input. |
| coverage | No | Present when surviving rows include a marketplace cluster at similar prices. That is not a retail floor — the cheapest marketplace listing is not the deal. The listings stay in the payload, each with its url. `next`, when present, is the Chrome extension page for shops WEM does not yet hold as partners. |
| currency | No | |
| degraded | No | Present when this call hit its time budget and skipped enrichment. The offers returned are COMPLETE — only the extras were dropped. A missing catalogue block or missing observed retailers does not mean WEM holds nothing, and no retry is needed. |
| filtered | No | Offers of this product WEM held back, tallied by reason. "Priced far below this product’s other offers" is a marketplace listing under 40% of what the product sells for elsewhere — the shape of a counterfeit, a part or a mislisted variant. Those prices are not in `offers`, `lowPrice`, `links`, `summary` or `priceHistory.low`: none is the cheapest, a deal or the 90-day low. The tally says how many were held back. |
| identity | No | How the shopper’s words reached this product. On `inferred`, WEM matched it by name (not by barcode) and the identity is not confirmed, even when `identityBasis` is `barcode`; on `exact`, the barcode itself resolved it. |
| lowPrice | No | Lowest CURRENT price in `offers` (read within 14 days). Null when no price is current or WEM holds none it may quote ; it is never taken from a stale or undated row, or from `unpriced`. |
| nextTool | No | Present only when `found` is false. It names `search_products` and the query. A named model that misses the catalogue is the ordinary case. |
| unpriced | No | Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. The row carries `priceNote` (e.g. "See price at Amazon") in place of a figure. No price is stated, estimated or compared for one; it is not the cheapest and is not counted in a lowest price or a saving. |
| highPrice | No | Highest current price in `offers`; null with lowPrice. |
| sameModel | No | Present only when the maker's own page says another model code is this product and a person at WEM has checked it. These are NOT offers for the product asked about: they are not part of `offers`, and none is this product's lowest price or the best deal. On verify_offer they are not part of the check: `verdict`, `cheapest`, `betterBy`, `summary` and the receipt are about the product asked about, and a cheaper sister code never makes the claimed price wrong. `summary` is written to be quoted as it is. `maker.host` is the source of the claim. `url` is WEM's comparison for that model, not a shop. When `relation` is `differs`, the `differences` are what the maker says differs, and its price is not a saving. Absent is not evidence that no equivalent exists. |
| disclosure | No | WEM’s affiliate disclosure for this answer, written to be quoted as it is. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. A version from an earlier answer may not fit this one: a row marked `affiliate: false` earns WEM nothing. |
| unavailable | No | Present and true only when WEM could not reach its catalogue at all. `found` is false for the same reason it is on an ordinary miss, so the two are indistinguishable without this flag. When it is set, WEM does not know whether it holds the product. The lookup could not be completed; it does not mean WEM has no offers or no price for it. `nextTool` is still present. |
| priceHistory | No | The 90-day low, for telling a real discount from a repackaged one. |
| identityBasis | No | How this product’s offers are grouped — NOT how the shopper’s words found the product; that is `identity`. `barcode`: the product carries a GTIN, so every offer here is that same item. `curated-grouping`: it carries none, and the grouping is an inference. This field does not make a result a barcode match: when `identity.strength` is `inferred`, WEM matched the product by name. |
| lastConfirmedAt | No | When WEM last actually read any price in this answer. Null means none of them can be dated, so the answer is not current. |
compare_productsCompare several productsRead-onlyInspect
Lays 2 to 5 listings from earlier search results side by side in comparison: each listing's price and currency, and its rating, shipping and features where the retailer source supplies them (many listings carry none). Each item needs the listing's provider and its id as product_id. Listings that cannot be found are left out, and fewer than two found is an error. Prices stay in each listing's own currency.
| Name | Required | Description | Default |
|---|---|---|---|
| products | Yes | 2 to 5 listings, each with `provider` and `product_id` as given in a search result. |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| comparison | Yes | |
| disclosure | Yes | WEM’s affiliate disclosure for this answer, written to be quoted as it is. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. A version from an earlier answer may not fit this one: a row marked `affiliate: false` earns WEM nothing. |
find_lowest_priceFind the lowest listed priceRead-onlyInspect
Picks one listing for a kind of product within the shopper's constraints, from WEM's catalogue and a live retailer search (a current catalogue match answers without the live search). Candidates are first filtered to plausible matches, so an accessory, another size, an out-of-stock listing or one priced far below the product's other offers is not picked. With no priorities, or with cheapest first, the lowest price wins; best_rated, free_shipping and fastest (has a delivery estimate) are weighed in the order given, where listings carry ratings or delivery details, and can outrank a lower price. WEM's commission is not a factor. recommendation is null with a reason when nothing matched confidently, when the matches differ in size, or when only stale prices remain; when coverage.kind is marketplace_only it is null but alternatives still lists the listings. recommendation.verified is true when WEM has recently observed that price at the retailer.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | One kind of product or product: a name, barcode, ASIN, WEM ID or wem3.ai/pl URL. A single query, not a list. | |
| currency | No | ISO 4217 code to quote in. Default GBP. Offers in other currencies are withheld, never converted. Pass the shopper's market explicitly — WEM does not infer currency or retailer market from IP. | |
| condition | No | Same effect as include_used: "any", "used" or "refurbished" also includes used and refurbished listings; any other value means new only. | |
| max_price | No | Budget cap, in `currency`. | |
| priorities | No | What matters most, in order. cheapest: lowest price. best_rated: higher rating. free_shipping: free delivery. fastest: states a delivery estimate. Weighed only where listings carry those details. | |
| include_used | No | If true, include used and refurbished listings. Default false — a used item is a different good, not a cheaper one. |
Output Schema
| Name | Required | Description |
|---|---|---|
| next | No | Present when WEM's set of offers is thin. chrome_extension is a page that compares the same product on any retailer page, including shops without an affiliate programme. |
| score | No | Internal ranking score. Not a price and not a rating — do not quote it. |
| reason | Yes | Why this was picked, or why nothing was. |
| search | No | Present when this result names no offer. `url` is WEM's results page for the query and `markdown` is the same link, pre-formatted. WEM searches retailers live on that page, including shops it holds no affiliate programme with, so an empty or withheld result here is not evidence the product is unavailable or unpriced. |
| partial | No | True when the live retailer fan-out hit its 3-second budget and some providers had not answered. The recommendation is the lowest among those that did. Do not call it the market floor, and do not retry automatically. |
| coverage | No | Present when surviving rows include a marketplace cluster at similar prices. That is not a retail floor — the cheapest marketplace listing is not the deal. The listings stay in the payload, each with its url. `next`, when present, is the Chrome extension page for shops WEM does not yet hold as partners. |
| degraded | No | Present when this call hit its time budget and skipped enrichment. The offers returned are COMPLETE — only the extras were dropped. A missing catalogue block or missing observed retailers does not mean WEM holds nothing, and no retry is needed. |
| filtered | No | Withheld candidates tallied by reason (e.g. accessories, another model, a bundle or multipack, a replica, a listing priced far below the product’s other offers). Report this count rather than implying the search was exhaustive, and never quote a withheld listing’s price as the cheapest or as a deal. |
| disclosure | No | WEM’s affiliate disclosure for this answer, written to be quoted as it is. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. A version from an earlier answer may not fit this one: a row marked `affiliate: false` earns WEM nothing. |
| alternatives | No | Listings still worth showing, including when recommendation is null. |
| catalogMatch | No | Offers WEM holds under one catalogue product. Check `identityBasis`: on `barcode` the product carries a GTIN and every offer here is that same item, so prefer them and cite their prices over anything in `products`. On `curated-grouping` the product carries no barcode, the grouping is an inference like any title match, and a cheaper row in `products` may well be the same item — see `cheaperElsewhere`. Whether the shopper’s words reached this product by barcode or by name is `identity`, a separate question: on `inferred`, say WEM matched it by name. |
| recommendation | Yes | The single lowest-priced plausible match, or null when nothing matched confidently. |
| liveSearchSkipped | No | True when a catalogue hit answered the question without spending retailer API quota. |
| pending_providers | No | Providers still running when the budget expired. Present only with partial. Their prices are not in this answer. |
get_categoriesList shopping categoriesARead-onlyInspect
Lists the six broad shopping categories WEM covers (electronics, fashion, beauty, home, sports, collectibles), each with example products, the shops WEM has read a price from in the last 14 days (busiest first, with how many shops there are in all) and the default currency (GBP). Use it to help a shopper narrow a vague request. It returns no prices, the category names are labels for the shopper, not filter values, and a shop on the list is not a promise that WEM holds a given product there: compare_offers says which shops WEM has for one product.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| currency | Yes | |
| providers | Yes | Shops WEM has read a price from in the last 14 days, busiest first, at most 40: one row per shop, with how many of its products WEM read. Say which shops WEM covers from this list, never from a shop's absence: it is not every shop WEM has ever held, and a shop on it may not sell the product the shopper wants (compare_offers says which shops WEM holds for one product). |
| shopCount | No | How many shops WEM read a price from in the last 14 days, listed or not. Null with an empty `providers` means the list could not be read just now, not that WEM has no shops. |
| categories | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, non-destructive), and the description adds substantive behavioral context beyond them: it returns no prices, category names are labels rather than filter values, and a listed shop does not guarantee product availability. These are non-obvious caveats an agent would otherwise mis-infer.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Content is front-loaded with what the tool returns, followed by usage and caveats. The second sentence is a dense run-on packing three separate caveats, which slightly hurts readability but every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, yet the description still frames the semantics an agent needs (no prices, labels not filters). For a zero-param, read-only listing tool, nothing relevant is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4; there is nothing for the description to disambiguate. It correctly spends no words on parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Lists the six broad shopping categories WEM covers') and enumerates the actual content (examples, shops with prices read in last 14 days, default currency). It also names the sibling it is not, compare_offers, so an agent can separate the two without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use ('Use it to help a shopper narrow a vague request') and an implicit when-not by routing single-product shop questions to compare_offers. Nothing is left to inference about which tool to pick.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_evidence_receiptLook up a verification receipt by idARead-onlyInspect
Fetches an evidence receipt by its id (wem-evr- followed by 32 hex characters), as issued with a verify_offer result. Returns the receipt's fields: verdict, observed_at, source, amount, currency and amount_minor, identity_method, verifier, standardVersion and issuedAt, with signed true and an HMAC signature when WEM signed it. It holds the citation, not the product's offers. A receipt issued moments ago may not be fetchable yet.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Receipt id (wem-evr- followed by 32 hex characters), as returned in a verify_offer result's receipt.id. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| amount | No | |
| signed | Yes | |
| source | Yes | |
| verdict | No | |
| currency | No | |
| issuedAt | No | |
| verifier | Yes | |
| signature | No | |
| observed_at | Yes | |
| amount_minor | No | |
| identity_method | No | |
| standardVersion | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/no-destructive/closed-world, but the description adds real behavioral context: the signed/HMAC signature condition, the specific field set returned, and the eventual-consistency caveat that a just-issued receipt may not be fetchable yet. That freshness warning is the kind of trait an annotation cannot express.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the or, and every sentence carries information — provenance, payload, scope boundary, freshness caveat. The mid-sentence field enumeration is long and partially redundant with the output schema, which keeps it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, read-only lookup with an output schema present, the description covers everything the agent needs: id provenance and format, what the payload contains, the signed-signature condition, and the not-yet-fetchable edge case. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single id parameter is already fully documented there, so the baseline is 3. The description adds only marginal value by repeating the id shape and noting the value originates from verify_offer's receipt.id.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource combination ('Fetches an evidence receipt by its id') and pins down the id format. It also ties the tool to its issuing sibling ('as issued with a verify_offer result'), so an agent can place it relative to verify_offer without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clear context: use it when you hold a receipt id produced by verify_offer, and the clarifying line 'It holds the citation, not the product's offers' steers an agent away from expecting offer data. It never states an explicit when-not or names a competing lookup tool, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_productGet one productRead-onlyInspect
Returns one product's details. Given provider and product_id from a search result, it returns that listing as its retailer source supplies it (title, price and link, with rating, shipping or features where the source has them); when the source cannot be reached it falls back to WEM's catalogue record of the listing, and an unknown listing is an error. Given wem_id, it returns that catalogue product with the retailer offers WEM holds for it.
| Name | Required | Description | Default |
|---|---|---|---|
| wem_id | No | WEM ID (W + 10 Crockford characters + check). Active catalogue products only. | |
| provider | No | Retailer source of the listing, as given in the search result (e.g. "amazon", "awin"). | |
| product_id | No | The listing's `id` from the search result. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | |
| url | Yes | WEM tracked link to the retailer page for this offer. WEM never takes payment. |
| brand | No | |
| image | No | |
| price | No | Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: the note stands in place of a figure. |
| title | No | |
| badges | No | |
| rating | No | |
| seller | No | |
| channel | No | retailer is a named shop (Boots, Currys). marketplace is AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers. |
| inStock | No | |
| currency | No | ISO 4217 code. |
| features | No | |
| provider | No | Retailer slug, e.g. "amazon", "currys". |
| shipping | No | Delivery as the retailer stated it: `free`, or `cost` in the offer currency. Absent or null means not stated: say delivery is shown at the shop, never that it is free. Offers are ordered by item price; add a stated cost before calling one cheaper delivered. |
| affiliate | No | False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. It is still a real offer, and its link is not affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` states whether all, some or none of the links are tracked. |
| priceNote | No | Present only when `price` is null: the words that stand in its place, e.g. "See price at Amazon". An Amazon price is shown only when Amazon’s API supplied it just now. |
| unitPrice | No | Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. Across sizes, value is compared on these, not on the prices: a smaller size is not cheaper because its price is lower. It reads beside the price ("£29.95, £99.83 per 100ml"). Absent does not mean the price is per unit. |
| disclosure | Yes | WEM’s affiliate disclosure for this answer, written to be quoted as it is. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. A version from an earlier answer may not fit this one: a row marked `affiliate: false` earns WEM nothing. |
| description | No | |
| priceStatus | No | `current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Those two read as "last seen £X on 8 Sep" or "price not dated", come after the current ones, and are not compared. Absent on a row a provider answered just now. |
| reviewCount | No | |
| priceQualifier | No | Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. It reads as "from £X"; it is not the item's price or the cheapest. Absent means the price is firm for the row as described. |
lookup_productsLook up several products by barcodeRead-onlyInspect
Looks up to 20 product identifiers in one call: barcodes (EAN/UPC/GTIN), Amazon ASINs, WEM IDs, catalogue slugs or wem3.ai/pl URLs. Each row has a status: found (WEM's catalogue holds it; the row gives its number of retailer offers, the lowest current price at a named retailer in the shopper's currency, a marketplace low where there is one, and a link to WEM's product page), not_found (WEM does not hold it yet, which says nothing about whether it exists or has a price), unrecognised (not an identifier, such as a product name) or not_checked (not reached in this call, so not a miss). Identifiers beyond 20 are counted in overLimit.
| Name | Required | Description | Default |
|---|---|---|---|
| currency | No | ISO 4217 code for the shopper's market. Default GBP. Lowest prices are quoted in this currency only, never converted; a product WEM holds only in another currency comes back found with lowPrice null and heldInCurrencies set. | |
| identifiers | Yes | 1-20 barcodes (EAN-13, UPC-A, EAN-8, GTIN-14), Amazon ASINs, WEM IDs, catalogue slugs or wem3.ai/pl URLs. Mixed kinds are fine; a comma-separated string is also accepted. Duplicates are looked up once. Each entry must be the identifier alone: not a product name, and not a name with a barcode in it. |
Output Schema
| Name | Required | Description |
|---|---|---|
| next | No | The WEM tool that answers the follow-up question, and what to pass it. |
| links | Yes | The WEM product-page links for found rows, pre-formatted to quote. Give these to the user when you name a found product. |
| counts | Yes | |
| results | Yes | |
| currency | Yes | |
| disclosure | Yes | WEM’s affiliate disclosure for this answer, written to be quoted as it is. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. A version from an earlier answer may not fit this one: a row marked `affiliate: false` earns WEM nothing. |
| unavailable | No | Present and true when WEM could not reach its catalogue. Rows it could not check are not_checked, not not_found — do not report them as products WEM lacks. |
| overLimitNote | No |
search_productsSearch products across retailersRead-onlyInspect
Searches WEM's catalogue and its connected retailer sources for products matching a query. The query can be a product name or an identifier: a barcode (EAN/UPC/GTIN), an Amazon ASIN, an MPN, a merchant SKU that names one catalogue product, a WEM ID or a wem3.ai/pl/{slug} URL, and several identifiers may be comma-separated. When the query identifies a product WEM holds, a catalogMatch block (catalogMatches for several) gives that product's retailer offers; a barcode, ASIN, WEM ID or URL match skips the live retailer search, so products then holds catalogue offers only. Barcode, ASIN and slug matches are identity-resolved; MPN, SKU and title matches are inferred. Accessories, bundles, other models and listings priced far below the product's other offers are withheld and counted by reason in filtered.
| Name | Required | Description | Default |
|---|---|---|---|
| gtin | No | A product barcode (EAN/UPC/GTIN) the host already has. When given, retailer sources are searched by this barcode instead of by the query words. | |
| limit | No | How many listings to request from each retailer source (default 10, max 30). The combined list can hold more. | |
| query | Yes | A product name, or an identifier: barcode (EAN/UPC/GTIN), ASIN, MPN, merchant SKU, WEM ID or wem3.ai/pl URL. Several identifiers may be comma-separated. | |
| sort_by | No | Order of the live retailer listings (default relevance). Not applied when the query identifies a product. | |
| category | No | Optional. Keeps only live retailer listings whose own category name matches this text exactly; catalogue matches ignore it. Leave it out unless the shopper names a retailer's category. | |
| currency | No | ISO 4217 code for the shopper's market. Default GBP. Results and price filters use this currency. | |
| max_price | No | Highest price to include, in `currency`. Applies to retailer listings, not to `catalogMatch`. | |
| min_price | No | Lowest price to include, in `currency`. Applies to retailer listings, not to `catalogMatch`. | |
| providers | No | Retailer sources to search live, e.g. ["amazon", "awin"]. Omit for all. Catalogue matches are not limited by it. |
Output Schema
| Name | Required | Description |
|---|---|---|
| next | No | Present when WEM's set of offers is thin. chrome_extension is a page that compares the same product on any retailer page, including shops without an affiliate programme. |
| query | Yes | |
| search | No | Present when this result names no offer. `url` is WEM's results page for the query and `markdown` is the same link, pre-formatted. WEM searches retailers live on that page, including shops it holds no affiliate programme with, so an empty or withheld result here is not evidence the product is unavailable or unpriced. |
| partial | No | True when the live retailer fan-out hit its 3-second budget and some providers had not answered. The rows returned are real; the market may be wider. Ask again for the rest. |
| coverage | No | Present when surviving rows include a marketplace cluster at similar prices. That is not a retail floor — the cheapest marketplace listing is not the deal. The listings stay in the payload, each with its url. `next`, when present, is the Chrome extension page for shops WEM does not yet hold as partners. |
| degraded | No | Present when this call hit its time budget and skipped enrichment. The offers returned are COMPLETE — only the extras were dropped. A missing catalogue block or missing observed retailers does not mean WEM holds nothing, and no retry is needed. |
| filtered | No | Withheld candidates tallied by reason (e.g. accessories, another model, a bundle or multipack, a replica, a listing priced far below the product’s other offers). Report this count rather than implying the search was exhaustive, and never quote a withheld listing’s price as the cheapest or as a deal. |
| products | Yes | |
| unpriced | No | Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. The row carries `priceNote` (e.g. "See price at Amazon") in place of a figure. No price is stated, estimated or compared for one; it is not the cheapest and is not counted in a lowest price or a saving. |
| disclosure | Yes | WEM’s affiliate disclosure for this answer, written to be quoted as it is. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. A version from an earlier answer may not fit this one: a row marked `affiliate: false` earns WEM nothing. |
| sizeSpread | No | Present when the returned rows are different sizes and the query named none, so price ordering is meaningless: the cheapest row is cheapest because it is less of the product. Do NOT name a cheapest, a lowest price, or a best deal across these rows. The size belongs beside every price. Where rows carry `unitPrice`, that is the like-for-like figure, and it is the figure to rank on when the question is which is better value. The rows are real listings, each with its url. |
| catalogMatch | No | Offers WEM holds under one catalogue product. Check `identityBasis`: on `barcode` the product carries a GTIN and every offer here is that same item, so prefer them and cite their prices over anything in `products`. On `curated-grouping` the product carries no barcode, the grouping is an inference like any title match, and a cheaper row in `products` may well be the same item — see `cheaperElsewhere`. Whether the shopper’s words reached this product by barcode or by name is `identity`, a separate question: on `inferred`, say WEM matched it by name. |
| totalResults | Yes | Count of products returned, after weak matches were withheld. |
| catalogMatches | No | Present when the query was a comma-separated batch of identifiers and more than one catalogue product resolved. Each entry has the same shape as `catalogMatch`. Prefer barcode-basis blocks; treat MPN/SKU/title blocks as inferred. |
| pending_providers | No | Providers still running when the budget expired. Present only with partial. |
search_promotionsFind current retailer promotionsARead-onlyInspect
Lists current promotions (sales and offers) that retailers in WEM's Awin affiliate programmes have published, for the shopper's market. Filter by merchant or by words in the offer. Each row gives the offer, its dates and a tracked link. A promotion is not a price, and it is not a discount on a product unless its terms say it covers that product. Checkout codes are shown only where the retailer's programme lets WEM publish them; other matching promotions are counted by reason in withheld, and a withheld code may still exist. An empty result covers only these programmes, not every offer a retailer runs.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max promotions to return (default 10, max 25). | |
| query | No | Words that must appear in the offer, e.g. "hoverboard" or "free delivery". | |
| currency | No | ISO 4217 code for the shopper's market: GBP (default) or USD. Promotions are regional, so this decides which market's offers are read. | |
| merchant | No | Retailer name, e.g. "iHoverboard". Omit for every retailer. |
Output Schema
| Name | Required | Description |
|---|---|---|
| more | No | Further matching promotions beyond `limit`. |
| note | No | |
| count | Yes | |
| links | Yes | The tracked links from `promotions`, pre-formatted. Give these to the user when you name a promotion. |
| market | No | ISO country code the promotions were read for. |
| reason | No | Present only when no promotion is shown. None of these means the retailer has no offer on — not_configured and upstream_error mean WEM could not look. |
| search | No | Present when this result names no offer. `url` is WEM's results page for the query and `markdown` is the same link, pre-formatted. WEM searches retailers live on that page, including shops it holds no affiliate programme with, so an empty or withheld result here is not evidence the product is unavailable or unpriced. |
| currency | Yes | |
| withheld | No | Matching promotions WEM did not show, counted by reason: notPublishable (a checkout code or offer the retailer’s programme does not let WEM publish; the code may well exist), notJoined, notActive, outsideMarket, noTrackedLink, otherPublisherLink, incompleteRecord. |
| disclosure | Yes | WEM’s affiliate disclosure for this answer, written to be quoted as it is. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. A version from an earlier answer may not fit this one: a row marked `affiliate: false` earns WEM nothing. |
| promotions | Yes | Ending soonest first. Each row is one live promotion WEM is allowed to show. |
| withheldNote | No | Quote this rather than paraphrase it when codes were withheld. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover the safety profile (readOnly, openWorld, non-destructive), and the description adds substantial operational context: checkout codes appear only where the retailer's programme permits publication, non-publishable matches are counted in `withheld` and may still exist, and an empty result covers only these programmes rather than all a retailer runs. These are exactly the nuances an agent cannot infer from structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with what the tool returns, then constraints, then edge cases; nearly every sentence carries distinct information. Slightly long at six sentences, but no sentence is pure filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists, the description needn't re-explain row format, yet it usefully flags that each row gives the offer, dates and a tracked link, and it covers the `withheld` edge case and empty-result semantics. Nothing needed to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so all four parameters are already documented, and the description largely restates them (currency governs the market read, merchant omitted means every retailer). It adds no new syntax or format detail beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (lists) and resource (current promotions from Awin affiliate programmes), scoped to the shopper's market, and explicitly distinguishes itself from pricing tools with 'A promotion is not a price, and it is not a discount on a product.' An agent can separate this from search_products, compare_offers or find_lowest_price without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usable context is given: filter by merchant or words in the offer, and the boundaries ('not a price', 'not a discount unless terms say it covers that product') tell the agent when this tool is inappropriate. It stops short of naming a sibling to use instead, so it doesn't reach the explicit alternative-routing of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
semantic_searchFind products by descriptionRead-onlyInspect
Searches WEM's partner-feed products by meaning, for a plain-language need such as "comfortable shoes for standing all day" or "gift for a 10 year old who likes science". If the description is a product identifier (a barcode, ASIN, MPN, merchant SKU or wem3.ai/pl URL), that product is looked up instead and the reply takes the keyword-search shape. When no products come back, reason says why: index_empty means nothing matched; no_embedding_key, no_catalogue_client, embedding_failed, query_failed and timed_out mean the semantic index could not be searched this time, which says nothing about whether such products exist.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max products to return (default 10, max 20). | |
| category | No | Optional. Keeps only products whose feed category matches this text exactly. | |
| provider | No | Optional. Keeps only products from this partner feed, e.g. "awin". | |
| max_price | No | Optional upper price bound, compared with each product's listed price (currencies are not converted). | |
| min_price | No | Optional lower price bound, compared with each product's listed price (currencies are not converted). | |
| description | Yes | Plain-language description of what the shopper needs. |
Output Schema
| Name | Required | Description |
|---|---|---|
| next | No | Present when WEM's set of offers is thin. chrome_extension is a page that compares the same product on any retailer page, including shops without an affiliate programme. |
| query | No | |
| reason | No | Present when semantic is false, and never a judgement on the shopper query. `index_empty` — the vector query ran and matched nothing. `no_catalogue_client` / `no_embedding_key` — WEM is misconfigured, not the catalogue empty. `embedding_failed` / `query_failed` — an upstream call failed; retrying later may succeed. `timed_out` — an upstream call did not answer in time; this says nothing about the catalogue. |
| search | No | Present when this result names no offer. `url` is WEM's results page for the query and `markdown` is the same link, pre-formatted. WEM searches retailers live on that page, including shops it holds no affiliate programme with, so an empty or withheld result here is not evidence the product is unavailable or unpriced. |
| filtered | No | Withheld candidates tallied by reason (e.g. accessories, another model, a bundle or multipack, a replica, a listing priced far below the product’s other offers). Report this count rather than implying the search was exhaustive, and never quote a withheld listing’s price as the cheapest or as a deal. |
| products | Yes | |
| semantic | No | True only when the vector path actually ran. |
| disclosure | Yes | WEM’s affiliate disclosure for this answer, written to be quoted as it is. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. A version from an earlier answer may not fit this one: a row marked `affiliate: false` earns WEM nothing. |
| catalogMatch | No | Offers WEM holds under one catalogue product. Check `identityBasis`: on `barcode` the product carries a GTIN and every offer here is that same item, so prefer them and cite their prices over anything in `products`. On `curated-grouping` the product carries no barcode, the grouping is an inference like any title match, and a cheaper row in `products` may well be the same item — see `cheaperElsewhere`. Whether the shopper’s words reached this product by barcode or by name is `identity`, a separate question: on `inferred`, say WEM matched it by name. |
| totalResults | Yes |
verify_offerCheck whether a price claim is trueInspect
Checks a price someone has claimed for a product against the prices WEM has itself observed at retailers (recent readings, within a small tolerance; not a live quote), and reports the cheapest observed offer. Identify the product by gtin (strongest), slug, wem_id, provider + externalId, or title (weakest, relevance-checked). retailer names the shop the claim is about; without it the nearest observed price at any shop is checked. Only offers in the claim's currency are compared. Verdicts: confirmed (WEM observed that price there), price_moved (WEM last observed a different price there), not_at_retailer (WEM has no observed price there, though it may hold a feed price), no_claim (no price given; the offers are returned), unknown_product (the product could not be resolved, or WEM holds no observed price for it in that currency). unknown_product means the claim could not be checked, not that it is false. lastConfirmedAt says when WEM last observed a price in the answer, or is null. Each call records an evidence receipt, whose id can be cited later.
| Name | Required | Description | Default |
|---|---|---|---|
| gtin | No | Product barcode: EAN-13, UPC-A, EAN-8 or GTIN-14. Strongest identifier. | |
| slug | No | WEM canonical slug, as in wem3.ai/pl/{slug}. | |
| price | No | The price being claimed. Omit to ask only for the observed offers. | |
| title | No | Product title. The weakest identifier: used only when no id is given, and only if it passes a relevance check. | |
| wem_id | No | WEM ID (W + 10 Crockford characters + check). Active catalogue products only. | |
| currency | No | ISO 4217 code for the claimed price. Default GBP. Only offers in this currency are compared. | |
| provider | No | With externalId: the retailer source of a listing that identifies the product, e.g. 'amazon'. To name the shop the claim is about, use `retailer`. | |
| retailer | No | The shop the price was claimed at, as a slug or display name. Omit to compare against every shop. | |
| externalId | No | That listing's own id (an ASIN, or the shop's own item number). Use with provider. |
Output Schema
| Name | Required | Description |
|---|---|---|
| offers | Yes | Prices WEM holds for this product, including indicative ones and shops it has no affiliate programme with yet. When `cheapest` is null, still show these rows and their links: they are a comparison, not a verification. Do not call them confirmed, and do not name a verified cheapest. |
| source | Yes | |
| product | No | |
| receipt | Yes | Citation handle for this answer. Field names follow ACP suggested_price (observed_at, source, amount). signed is true only when WEM issued an HMAC with a dedicated key; otherwise false (fail closed). |
| summary | Yes | Written so quoting it verbatim is accurate. Prefer quoting it to paraphrasing the verdict code. |
| verdict | Yes | |
| betterBy | No | Saving from taking `cheapest` over the claimed price. Never negative. |
| cheapest | No | |
| identity | No | How the product was identified — a separate question from whether the price checks out. Never present a `strength` of "inferred" as a verified identity. |
| sameModel | No | Present only when the maker's own page says another model code is this product and a person at WEM has checked it. These are NOT offers for the product asked about: they are not part of `offers`, and none is this product's lowest price or the best deal. On verify_offer they are not part of the check: `verdict`, `cheapest`, `betterBy`, `summary` and the receipt are about the product asked about, and a cheaper sister code never makes the claimed price wrong. `summary` is written to be quoted as it is. `maker.host` is the source of the claim. `url` is WEM's comparison for that model, not a shop. When `relation` is `differs`, the `differences` are what the maker says differs, and its price is not a saving. Absent is not evidence that no equivalent exists. |
| disclosure | Yes | WEM’s affiliate disclosure for this answer, written to be quoted as it is. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. A version from an earlier answer may not fit this one: a row marked `affiliate: false` earns WEM nothing. |
| resolvedBy | No | Which identifier resolved the product. |
| claimMatched | No | |
| comparisonSet | No | How wide the comparison behind `cheapest` was. `exhaustive` is always false: WEM does not see every retailer, so `cheapest` is the lowest offer WEM holds, never the lowest that exists. Relay it as such. |
| lastConfirmedAt | No | When WEM last read a price among the offers compared — the freshness of this answer. Null means none of them carries a dated reading: say the prices are undated. |
| toleranceApplied | No |
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
- Changed
compare_offers1 field changed- changed
Output schema / properties / coverage / properties / provider / descriptionPrevious value: -"aliexpress, or marketplace when mixed."New value: +"The marketplace (e.g. aliexpress), or marketplace when mixed."
- Changed
find_lowest_price1 field changed- changed
Output schema / properties / coverage / properties / provider / descriptionPrevious value: -"aliexpress, or marketplace when mixed."New value: +"The marketplace (e.g. aliexpress), or marketplace when mixed."
- Changed
lookup_products1 field changed- changed
Output schema / properties / results / items / properties / marketplaceLowPrice / descriptionPrevious value: -"Cheapest marketplace listing (AliExpress…), present only when it undercuts lowPrice or no named retailer holds the product. A seller’s price, not a retail floor: never quote it as the product’s price or the cheapest."New value: +"Cheapest marketplace listing (AliExpress, Temu…), present only when it undercuts lowPrice or no named retailer holds the product. A seller’s price, not a retail floor: never quote it as the product’s price or the cheapest."
- Changed
search_products1 field changed- changed
Output schema / properties / coverage / properties / provider / descriptionPrevious value: -"aliexpress, or marketplace when mixed."New value: +"The marketplace (e.g. aliexpress), or marketplace when mixed."
8 tool updates
- Changed
compare_offers3 fields changed- changed
Output schema / properties / coverage / properties / provider / descriptionPrevious value: -"ebay, aliexpress, or marketplace when mixed."New value: +"aliexpress, or marketplace when mixed." - changed
Output schema / properties / offers / items / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / offers / items / properties / provider / descriptionPrevious value: -"Retailer slug, e.g. \"ebay\", \"currys\"."New value: +"Retailer slug, e.g. \"amazon\", \"currys\"."
- Changed
compare_products2 fields changed- changed
Output schema / properties / comparison / items / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / comparison / items / properties / provider / descriptionPrevious value: -"Retailer slug, e.g. \"ebay\", \"currys\"."New value: +"Retailer slug, e.g. \"amazon\", \"currys\"."
- Changed
find_lowest_price7 fields changed- changed
Output schema / properties / alternatives / items / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / alternatives / items / properties / provider / descriptionPrevious value: -"Retailer slug, e.g. \"ebay\", \"currys\"."New value: +"Retailer slug, e.g. \"amazon\", \"currys\"." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / provider / descriptionPrevious value: -"Retailer slug, e.g. \"ebay\", \"currys\"."New value: +"Retailer slug, e.g. \"amazon\", \"currys\"." - changed
Output schema / properties / coverage / properties / provider / descriptionPrevious value: -"ebay, aliexpress, or marketplace when mixed."New value: +"aliexpress, or marketplace when mixed." - changed
Output schema / properties / recommendation / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / recommendation / properties / provider / descriptionPrevious value: -"Retailer slug, e.g. \"ebay\", \"currys\"."New value: +"Retailer slug, e.g. \"amazon\", \"currys\"."
- Changed
get_product3 fields changed- changed
Input schema / properties / provider / descriptionPrevious value: -"Retailer source of the listing, as given in the search result (e.g. \"ebay\", \"awin\")."New value: +"Retailer source of the listing, as given in the search result (e.g. \"amazon\", \"awin\")." - changed
Output schema / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / provider / descriptionPrevious value: -"Retailer slug, e.g. \"ebay\", \"currys\"."New value: +"Retailer slug, e.g. \"amazon\", \"currys\"."
- Changed
lookup_products1 field changed- changed
Output schema / properties / results / items / properties / marketplaceLowPrice / descriptionPrevious value: -"Cheapest marketplace listing (eBay, AliExpress…), present only when it undercuts lowPrice or no named retailer holds the product. A seller’s price, not a retail floor: never quote it as the product’s price or the cheapest."New value: +"Cheapest marketplace listing (AliExpress…), present only when it undercuts lowPrice or no named retailer holds the product. A seller’s price, not a retail floor: never quote it as the product’s price or the cheapest."
- Changed
search_products8 fields changed- changed
Input schema / properties / providers / descriptionPrevious value: -"Retailer sources to search live, e.g. [\"ebay\", \"awin\"]. Omit for all. Catalogue matches are not limited by it."New value: +"Retailer sources to search live, e.g. [\"amazon\", \"awin\"]. Omit for all. Catalogue matches are not limited by it." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / provider / descriptionPrevious value: -"Retailer slug, e.g. \"ebay\", \"currys\"."New value: +"Retailer slug, e.g. \"amazon\", \"currys\"." - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / provider / descriptionPrevious value: -"Retailer slug, e.g. \"ebay\", \"currys\"."New value: +"Retailer slug, e.g. \"amazon\", \"currys\"." - changed
Output schema / properties / coverage / properties / provider / descriptionPrevious value: -"ebay, aliexpress, or marketplace when mixed."New value: +"aliexpress, or marketplace when mixed." - changed
Output schema / properties / products / items / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / products / items / properties / provider / descriptionPrevious value: -"Retailer slug, e.g. \"ebay\", \"currys\"."New value: +"Retailer slug, e.g. \"amazon\", \"currys\"."
- Changed
semantic_search4 fields changed- changed
Output schema / properties / catalogMatch / properties / offers / items / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / provider / descriptionPrevious value: -"Retailer slug, e.g. \"ebay\", \"currys\"."New value: +"Retailer slug, e.g. \"amazon\", \"currys\"." - changed
Output schema / properties / products / items / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / products / items / properties / provider / descriptionPrevious value: -"Retailer slug, e.g. \"ebay\", \"currys\"."New value: +"Retailer slug, e.g. \"amazon\", \"currys\"."
- Changed
verify_offer2 fields changed- changed
Input schema / properties / externalId / descriptionPrevious value: -"That listing's own id (ASIN, eBay item number). Use with provider."New value: +"That listing's own id (an ASIN, or the shop's own item number). Use with provider." - changed
Input schema / properties / provider / descriptionPrevious value: -"With externalId: the retailer source of a listing that identifies the product, e.g. 'amazon' or 'ebay'. To name the shop the claim is about, use `retailer`."New value: +"With externalId: the retailer source of a listing that identifies the product, e.g. 'amazon'. To name the shop the claim is about, use `retailer`."
1 tool update
- Changed
compare_offers4 fields changed- changed
Output schema / descriptionPrevious value: -"The retailer offers WEM holds for one catalogue product, current prices first and each group cheapest first. When `found` is false WEM simply does not hold this product yet — that is a normal answer, not a failure, and it says nothing about whether the product exists or what it costs. `nextTool` then names `search_products` and the query. An empty catalogue result is not a statement that the product is unavailable or unpriced; the live retailer search is a separate lookup and routinely finds supply this catalogue has not ingested."New value: +"The retailer offers WEM holds for one catalogue product, current prices first and each group cheapest first. When `found` is false WEM simply does not hold this product yet — that is a normal answer, not a failure, and it says nothing about whether the product exists or what it costs. `nextTool` then names `search_products` and the query. An empty catalogue result is not a statement that the product is unavailable or unpriced." - changed
Output schema / properties / nextTool / descriptionPrevious value: -"Present only when `found` is false. It names `search_products` and the query. A named model that misses the catalogue is the ordinary case; the live search is a separate lookup."New value: +"Present only when `found` is false. It names `search_products` and the query. A named model that misses the catalogue is the ordinary case." - changed
Output schema / properties / search / descriptionPrevious value: -"Present when this result names no offer. `url` is WEM's results page for the query and `markdown` is the same link, pre-formatted. WEM searches retailers live on that page, including shops it holds no affiliate programme with, so an empty or withheld result here is not evidence the product is unavailable or unpriced."New value: +"Present when this result names no offer. `url` is WEM's results page for the query and `markdown` is the same link, pre-formatted. This tool reads the catalogue only, so an empty result here is not evidence the product is unavailable or unpriced." - changed
Output schema / properties / unavailable / descriptionPrevious value: -"Present and true only when WEM could not reach its catalogue at all. `found` is false for the same reason it is on an ordinary miss, so the two are indistinguishable without this flag. When it is set, WEM does not know whether it holds the product. The lookup could not be completed; it does not mean WEM has no offers or no price for it. `nextTool` is still present, because the live retailer search does not depend on the catalogue."New value: +"Present and true only when WEM could not reach its catalogue at all. `found` is false for the same reason it is on an ordinary miss, so the two are indistinguishable without this flag. When it is set, WEM does not know whether it holds the product. The lookup could not be completed; it does not mean WEM has no offers or no price for it. `nextTool` is still present."
1 tool update
- Changed
get_categories3 fields changed- changed
Output schema / properties / providers / descriptionPrevious value: -"Retailers currently enabled. WEM compares only feeds it is licensed to use."New value: +"Shops WEM has read a price from in the last 14 days, busiest first, at most 40: one row per shop, with how many of its products WEM read. Say which shops WEM covers from this list, never from a shop's absence: it is not every shop WEM has ever held, and a shop on it may not sell the product the shopper wants (compare_offers says which shops WEM holds for one product)." - added
Output schema / properties / providers / items / properties / productsAdded value: +{ + "description": "Products WEM read a price for at this shop in the last 14 days.", + "type": "integer" +} - added
Output schema / properties / shopCountAdded value: +{ + "description": "How many shops WEM read a price from in the last 14 days, listed or not. Null with an empty `providers` means the list could not be read just now, not that WEM has no shops.", + "type": [ + "integer", + "null" + ] +}
6 tool updates
- Changed
compare_offers1 field changed- added
Output schema / properties / offers / items / properties / shipping / descriptionAdded value: +"Delivery as the retailer stated it: `free`, or `cost` in the offer currency. Absent or null means not stated: say delivery is shown at the shop, never that it is free. Offers are ordered by item price; add a stated cost before calling one cheaper delivered."
- Changed
compare_products1 field changed- added
Output schema / properties / comparison / items / properties / shipping / descriptionAdded value: +"Delivery as the retailer stated it: `free`, or `cost` in the offer currency. Absent or null means not stated: say delivery is shown at the shop, never that it is free. Offers are ordered by item price; add a stated cost before calling one cheaper delivered."
- Changed
find_lowest_price3 fields changed- added
Output schema / properties / alternatives / items / properties / shipping / descriptionAdded value: +"Delivery as the retailer stated it: `free`, or `cost` in the offer currency. Absent or null means not stated: say delivery is shown at the shop, never that it is free. Offers are ordered by item price; add a stated cost before calling one cheaper delivered." - added
Output schema / properties / catalogMatch / properties / offers / items / properties / shipping / descriptionAdded value: +"Delivery as the retailer stated it: `free`, or `cost` in the offer currency. Absent or null means not stated: say delivery is shown at the shop, never that it is free. Offers are ordered by item price; add a stated cost before calling one cheaper delivered." - added
Output schema / properties / recommendation / properties / shipping / descriptionAdded value: +"Delivery as the retailer stated it: `free`, or `cost` in the offer currency. Absent or null means not stated: say delivery is shown at the shop, never that it is free. Offers are ordered by item price; add a stated cost before calling one cheaper delivered."
- Changed
get_product1 field changed- added
Output schema / properties / shipping / descriptionAdded value: +"Delivery as the retailer stated it: `free`, or `cost` in the offer currency. Absent or null means not stated: say delivery is shown at the shop, never that it is free. Offers are ordered by item price; add a stated cost before calling one cheaper delivered."
- Changed
search_products3 fields changed- added
Output schema / properties / catalogMatch / properties / offers / items / properties / shipping / descriptionAdded value: +"Delivery as the retailer stated it: `free`, or `cost` in the offer currency. Absent or null means not stated: say delivery is shown at the shop, never that it is free. Offers are ordered by item price; add a stated cost before calling one cheaper delivered." - added
Output schema / properties / catalogMatches / items / properties / offers / items / properties / shipping / descriptionAdded value: +"Delivery as the retailer stated it: `free`, or `cost` in the offer currency. Absent or null means not stated: say delivery is shown at the shop, never that it is free. Offers are ordered by item price; add a stated cost before calling one cheaper delivered." - added
Output schema / properties / products / items / properties / shipping / descriptionAdded value: +"Delivery as the retailer stated it: `free`, or `cost` in the offer currency. Absent or null means not stated: say delivery is shown at the shop, never that it is free. Offers are ordered by item price; add a stated cost before calling one cheaper delivered."
- Changed
semantic_search2 fields changed- added
Output schema / properties / catalogMatch / properties / offers / items / properties / shipping / descriptionAdded value: +"Delivery as the retailer stated it: `free`, or `cost` in the offer currency. Absent or null means not stated: say delivery is shown at the shop, never that it is free. Offers are ordered by item price; add a stated cost before calling one cheaper delivered." - added
Output schema / properties / products / items / properties / shipping / descriptionAdded value: +"Delivery as the retailer stated it: `free`, or `cost` in the offer currency. Absent or null means not stated: say delivery is shown at the shop, never that it is free. Offers are ordered by item price; add a stated cost before calling one cheaper delivered."
10 tool updates
- Changed
compare_offers43 fields changed- changed
Input schema / properties / currency / descriptionPrevious value: -"ISO 4217 code for the shopper's market. Default GBP. Decides which market's offers WEM returns from its catalogue, not just how the answer reads — pass it explicitly, because WEM does not infer the market from IP. When WEM holds the product only in another currency it says so rather than presenting a foreign listing as the answer."New value: +"ISO 4217 code for the shopper's market. Default GBP. Decides which market's offers WEM returns from its catalogue, not just how the answer reads ; WEM does not infer the market from IP. When WEM holds the product only in another currency it says so rather than presenting a foreign listing as the answer." - changed
Input schema / properties / gtin / descriptionPrevious value: -"Product barcode: EAN-13, UPC-A, EAN-8 or GTIN-14. Preferred key."New value: +"Product barcode: EAN-13, UPC-A, EAN-8 or GTIN-14. The strongest identifier." - changed
Input schema / properties / title / descriptionPrevious value: -"Product or model name, or a bare MPN / merchant SKU (e.g. AF400UK). Weakest identifier — used only when no barcode, slug, or WEM ID is available. Same relevance gate as verify_offer; a miss means fall back to search_products, not a guess."New value: +"Product or model name, or an ASIN, MPN or merchant SKU (e.g. AF400UK). The weakest identifier: used only when no barcode, slug or WEM ID is given, and only if it passes a relevance check; otherwise `found` is false rather than a guess." - changed
Output schema / descriptionPrevious value: -"Every verified retailer offer for one catalogue product, cheapest first. When `found` is false WEM simply does not hold this product yet — that is a normal answer, not a failure, and it says nothing about whether the product exists or what it costs. Call `search_products` with `nextTool.query` before telling the user anything; reporting \"WEM returns nothing\" without doing so is wrong, because the live retailer search routinely finds supply this catalogue has not ingested."New value: +"The retailer offers WEM holds for one catalogue product, current prices first and each group cheapest first. When `found` is false WEM simply does not hold this product yet — that is a normal answer, not a failure, and it says nothing about whether the product exists or what it costs. `nextTool` then names `search_products` and the query. An empty catalogue result is not a statement that the product is unavailable or unpriced; the live retailer search is a separate lookup and routinely finds supply this catalogue has not ingested." - changed
Output schema / properties / coverage / descriptionPrevious value: -"Present when surviving rows include a marketplace cluster at similar prices. That is not a retail floor — do not name the cheapest marketplace listing as the deal. The listings are still in the payload; give the user those links. If `next` points at the Chrome extension, send the shopper there for shops WEM does not yet hold as partners."New value: +"Present when surviving rows include a marketplace cluster at similar prices. That is not a retail floor — the cheapest marketplace listing is not the deal. The listings stay in the payload, each with its url. `next`, when present, is the Chrome extension page for shops WEM does not yet hold as partners." - changed
Output schema / properties / degraded / descriptionPrevious value: -"Present when this call hit its time budget and skipped enrichment. The offers returned are COMPLETE — only the extras were dropped. Do not report a missing catalogue block or missing observed retailers as WEM holding nothing, and do not retry automatically."New value: +"Present when this call hit its time budget and skipped enrichment. The offers returned are COMPLETE — only the extras were dropped. A missing catalogue block or missing observed retailers does not mean WEM holds nothing, and no retry is needed." - changed
Output schema / properties / disclosure / descriptionPrevious value: -"Disclosure to relay once per answer, verbatim. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. Never substitute the version you saw last time — a row marked `affiliate: false` earns WEM nothing, and saying otherwise misdescribes it to the shopper."New value: +"WEM’s affiliate disclosure for this answer, written to be quoted as it is. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. A version from an earlier answer may not fit this one: a row marked `affiliate: false` earns WEM nothing." - changed
Output schema / properties / filtered / descriptionPrevious value: -"Offers of this product WEM held back, tallied by reason. \"Priced far below this product’s other offers\" is a marketplace listing under 40% of what the product sells for elsewhere — the shape of a counterfeit, a part or a mislisted variant. Those prices are not in `offers`, `lowPrice`, `links`, `summary` or `priceHistory.low`: never quote one as the cheapest, a deal or the 90-day low. Say how many were held back."New value: +"Offers of this product WEM held back, tallied by reason. \"Priced far below this product’s other offers\" is a marketplace listing under 40% of what the product sells for elsewhere — the shape of a counterfeit, a part or a mislisted variant. Those prices are not in `offers`, `lowPrice`, `links`, `summary` or `priceHistory.low`: none is the cheapest, a deal or the 90-day low. The tally says how many were held back." - changed
Output schema / properties / found / descriptionPrevious value: -"False when the product is not in WEM’s catalogue. The rest of the fields below are then absent — do not read that as the product being unavailable or unpriced. Check `unavailable` before describing the result, then follow `nextTool`."New value: +"False when the product is not in WEM’s catalogue. The rest of the fields below are then absent ; that does not mean the product is unavailable or unpriced. `unavailable` distinguishes an outage from a miss. `nextTool`, when present, names the next lookup." - changed
Output schema / properties / identity / descriptionPrevious value: -"How the shopper’s words reached this product. Decides how you describe the match: on `inferred`, say WEM matched it by name (not by barcode) and do not call the identity confirmed, even when `identityBasis` is `barcode`; on `exact`, the barcode itself resolved it."New value: +"How the shopper’s words reached this product. On `inferred`, WEM matched it by name (not by barcode) and the identity is not confirmed, even when `identityBasis` is `barcode`; on `exact`, the barcode itself resolved it." - changed
Output schema / properties / identityBasis / descriptionPrevious value: -"How this product’s offers are grouped — NOT how the shopper’s words found the product; that is `identity`. `barcode`: the product carries a GTIN, so every offer here is that same item. `curated-grouping`: it carries none, and the grouping is an inference. Never call a result a barcode match on the strength of this field: when `identity.strength` is `inferred`, say WEM matched the product by name."New value: +"How this product’s offers are grouped — NOT how the shopper’s words found the product; that is `identity`. `barcode`: the product carries a GTIN, so every offer here is that same item. `curated-grouping`: it carries none, and the grouping is an inference. This field does not make a result a barcode match: when `identity.strength` is `inferred`, WEM matched the product by name." - changed
Output schema / properties / lastConfirmedAt / descriptionPrevious value: -"When WEM last actually read any price in this answer. Null means none of them can be dated — say so rather than implying the answer is current."New value: +"When WEM last actually read any price in this answer. Null means none of them can be dated, so the answer is not current." - changed
Output schema / properties / links / descriptionPrevious value: -"The links from `offers`, cheapest first, pre-formatted to quote. Each opens the retailer’s page for the offer WEM priced; a retailer URL found elsewhere may be a different listing or price. State them in text even when the host renders a WEM card: the card may not reach the user."New value: +"The links from `offers`, cheapest first, pre-formatted. Each opens the retailer’s page for the offer WEM priced; a retailer URL found elsewhere may be a different listing or price. The same links are in this array and, when a host renders one, in the card." - changed
Output schema / properties / links / items / properties / price / descriptionPrevious value: -"Null for a listing in `unpriced`: its markdown says \"see price at Amazon\", and so must you."New value: +"Null for a listing in `unpriced`. The markdown says \"see price at Amazon\" in place of a figure." - changed
Output schema / properties / links / items / properties / url / descriptionPrevious value: -"WEM tracked redirect. Relay it exactly; never rewrite or shorten it."New value: +"WEM tracked redirect. The full URL; a shortened or rewritten form is a different link." - changed
Output schema / properties / lowPrice / descriptionPrevious value: -"Lowest CURRENT price in `offers` (read within 14 days). Null when no price is current or WEM holds none it may quote — never fill it from a stale or undated row, or from `unpriced`."New value: +"Lowest CURRENT price in `offers` (read within 14 days). Null when no price is current or WEM holds none it may quote ; it is never taken from a stale or undated row, or from `unpriced`." - changed
Output schema / properties / next / descriptionPrevious value: -"Where to send the shopper when WEM's set is thin. chrome_extension means compare the same product on any retailer page — WEM shows that price even without an affiliate programme."New value: +"Present when WEM's set of offers is thin. chrome_extension is a page that compares the same product on any retailer page, including shops without an affiliate programme." - changed
Output schema / properties / nextTool / descriptionPrevious value: -"Present only when `found` is false: the call to make next, with the text to pass. This is the recovery path, not a suggestion — a named model that misses the catalogue is the ordinary case, and the live search is where its offers are."New value: +"Present only when `found` is false. It names `search_products` and the query. A named model that misses the catalogue is the ordinary case; the live search is a separate lookup." - changed
Output schema / properties / offers / descriptionPrevious value: -"Current prices first (`priceStatus`), each group ascending by price; a stale or undated row is listed, never compared. Barcode, slug and WEM ID rows are the product. A title match is inferred — check identity.strength before stating it as exact."New value: +"Current prices first (`priceStatus`), each group ascending by price; a stale or undated row is listed, never compared. Barcode, slug and WEM ID rows are the product. A title match is inferred; `identity.strength` says which." - changed
Output schema / properties / offers / items / properties / affiliate / descriptionPrevious value: -"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. It is still a real offer, and its link is not affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` states whether all, some or none of the links are tracked." - changed
Output schema / properties / offers / items / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. Do not present a marketplace cluster as competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / offers / items / properties / lastSeenAt / descriptionPrevious value: -"When WEM last READ this price from the retailer or a datafeed — the same reading `priceAgeDays` counts from, so the two always agree. Null means WEM cannot date the price: say it is undated, never that it is current."New value: +"When WEM last READ this price from the retailer or a datafeed — the same reading `priceAgeDays` counts from, so the two always agree. Null means WEM cannot date the price: it is undated, not current." - changed
Output schema / properties / offers / items / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: the note stands in place of a figure." - changed
Output schema / properties / offers / items / properties / priceAgeDays / descriptionPrevious value: -"Calendar days (UK time) since WEM last READ this price: 0 read today, 1 yesterday. Null means WEM cannot say. Report null as undated; never present it as current."New value: +"Calendar days (UK time) since WEM last READ this price: 0 read today, 1 yesterday. Null means WEM cannot say. Null is undated, not current." - changed
Output schema / properties / offers / items / properties / priceNote / descriptionPrevious value: -"Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now."New value: +"Present only when `price` is null: the words that stand in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now." - changed
Output schema / properties / offers / items / properties / priceQualifier / descriptionPrevious value: -"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. Quote it as \"from £X\", never as the price or the cheapest. Absent means the price is firm for the row as described."New value: +"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. It reads as \"from £X\"; it is not the item's price or the cheapest. Absent means the price is firm for the row as described." - changed
Output schema / properties / offers / items / properties / priceRefresh / descriptionPrevious value: -"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `none` nothing on a schedule. `none` means the figure will not move on its own however long it sits — say so rather than quoting it flat, and date it with `priceAgeDays`."New value: +"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `none` nothing on a schedule. `none` means the figure will not move on its own however long it sits ; `priceAgeDays` dates it." - changed
Output schema / properties / offers / items / properties / priceStatus / descriptionPrevious value: -"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now."New value: +"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Those two read as \"last seen £X on 8 Sep\" or \"price not dated\", come after the current ones, and are not compared. Absent on a row a provider answered just now." - changed
Output schema / properties / offers / items / properties / unitPrice / descriptionPrevious value: -"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit."New value: +"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. Across sizes, value is compared on these, not on the prices: a smaller size is not cheaper because its price is lower. It reads beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit." - changed
Output schema / properties / offers / items / properties / url / descriptionPrevious value: -"WEM tracked link to the retailer. Send the user here — WEM never takes payment."New value: +"WEM tracked link to the retailer page for this offer. WEM never takes payment." - removed
Output schema / properties / offers / items / properties / verifiedRemoved value: -{ - "type": "boolean" -} - changed
Output schema / properties / product / properties / image / descriptionPrevious value: -"Product photo, served from wem3.ai. Null when none is available — do not substitute one."New value: +"Product photo, served from wem3.ai. Null when none is available." - changed
Output schema / properties / product / properties / wem_id / descriptionPrevious value: -"WEM ID of this active product. Omit when unknown; never invent one."New value: +"WEM ID of this active product. Null when unknown." - changed
Output schema / properties / reason / descriptionPrevious value: -"Present only when `found` is false: which identifier missed, and why. When `unavailable` is true this describes the outage rather than a missing product — quote it as the reason the lookup failed, not as a fact about the product."New value: +"Present only when `found` is false: which identifier missed, and why. When `unavailable` is true this describes the outage rather than a missing product ; it is the reason the lookup failed, not a fact about the product." - changed
Output schema / properties / sameModel / descriptionPrevious value: -"Present only when the maker's own page says another model code is this product and a person at WEM has checked it. These are NOT offers for the product asked about: never merge them into `offers`, never call one this product's lowest price or the best deal. On verify_offer they are not part of the check: `verdict`, `cheapest`, `betterBy`, `summary` and the receipt are about the product asked about, and a cheaper sister code never makes the claimed price wrong. Mention it as a separate line: quote `summary`, name the maker's page (`maker.host`) as the source, and link `url`, WEM's comparison for that model, not a shop. When `relation` is `differs`, name the `differences` and never call its price a saving. Absent is not evidence that no equivalent exists."New value: +"Present only when the maker's own page says another model code is this product and a person at WEM has checked it. These are NOT offers for the product asked about: they are not part of `offers`, and none is this product's lowest price or the best deal. On verify_offer they are not part of the check: `verdict`, `cheapest`, `betterBy`, `summary` and the receipt are about the product asked about, and a cheaper sister code never makes the claimed price wrong. `summary` is written to be quoted as it is. `maker.host` is the source of the claim. `url` is WEM's comparison for that model, not a shop. When `relation` is `differs`, the `differences` are what the maker says differs, and its price is not a saving. Absent is not evidence that no equivalent exists." - changed
Output schema / properties / sameModel / items / properties / cheapest / descriptionPrevious value: -"The other model's cheapest named shop. Null when no named shop has an in-stock price for it. Give its age; never present it as current without one."New value: +"The other model's cheapest named shop. Null when no named shop has an in-stock price for it. `priceAgeDays` gives its age; without one it is not current." - changed
Output schema / properties / sameModel / items / properties / maker / descriptionPrevious value: -"The maker's own page that says so: the proof. Cite it; WEM is not the source of the claim."New value: +"The maker's own page that says so: the proof. WEM is not the source of the claim." - changed
Output schema / properties / sameModel / items / properties / url / descriptionPrevious value: -"WEM's comparison for that model. Link this, not a shop."New value: +"WEM's comparison for that model, not a shop." - changed
Output schema / properties / search / descriptionPrevious value: -"Present when this result names no offer. GIVE THE USER THIS LINK — it is the answer when WEM has nothing else to say, and `markdown` is ready to paste. WEM searches retailers live on that page, including shops it holds no affiliate programme with, so an empty or withheld result here is not evidence the product is unavailable or unpriced."New value: +"Present when this result names no offer. `url` is WEM's results page for the query and `markdown` is the same link, pre-formatted. WEM searches retailers live on that page, including shops it holds no affiliate programme with, so an empty or withheld result here is not evidence the product is unavailable or unpriced." - changed
Output schema / properties / unavailable / descriptionPrevious value: -"Present and true only when WEM could not reach its catalogue at all. `found` is false for the same reason it is on an ordinary miss, so the two are indistinguishable without this flag. When it is set, WEM does not know whether it holds the product: say the lookup could not be completed, never that WEM has no offers, no price, or does not stock it. Still call `nextTool` — the live retailer search does not depend on the catalogue."New value: +"Present and true only when WEM could not reach its catalogue at all. `found` is false for the same reason it is on an ordinary miss, so the two are indistinguishable without this flag. When it is set, WEM does not know whether it holds the product. The lookup could not be completed; it does not mean WEM has no offers or no price for it. `nextTool` is still present, because the live retailer search does not depend on the catalogue." - changed
Output schema / properties / unpriced / descriptionPrevious value: -"Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. Give the link with `priceNote` (\"See price at Amazon\"). Never state, estimate or compare a price for one, never call it the cheapest, and never count it in a lowest price or a saving."New value: +"Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. The row carries `priceNote` (e.g. \"See price at Amazon\") in place of a figure. No price is stated, estimated or compared for one; it is not the cheapest and is not counted in a lowest price or a saving." - changed
Output schema / properties / unpriced / items / properties / priceNote / descriptionPrevious value: -"What to show where a price would be, e.g. \"See price at Amazon\"."New value: +"What stands where a price would be, e.g. \"See price at Amazon\"." - changed
Output schema / properties / unpriced / items / properties / url / descriptionPrevious value: -"WEM tracked link. Relay it exactly."New value: +"WEM tracked link. The full URL; a shortened form is a different link."
- Changed
compare_products10 fields changed- changed
Input schema / properties / products / descriptionPrevious value: -"List of products to compare (2-5 items)"New value: +"2 to 5 listings, each with `provider` and `product_id` as given in a search result." - changed
Output schema / properties / comparison / items / properties / affiliate / descriptionPrevious value: -"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. It is still a real offer, and its link is not affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` states whether all, some or none of the links are tracked." - changed
Output schema / properties / comparison / items / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. Do not present a marketplace cluster as competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / comparison / items / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: the note stands in place of a figure." - changed
Output schema / properties / comparison / items / properties / priceNote / descriptionPrevious value: -"Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now."New value: +"Present only when `price` is null: the words that stand in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now." - changed
Output schema / properties / comparison / items / properties / priceQualifier / descriptionPrevious value: -"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. Quote it as \"from £X\", never as the price or the cheapest. Absent means the price is firm for the row as described."New value: +"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. It reads as \"from £X\"; it is not the item's price or the cheapest. Absent means the price is firm for the row as described." - changed
Output schema / properties / comparison / items / properties / priceStatus / descriptionPrevious value: -"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now."New value: +"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Those two read as \"last seen £X on 8 Sep\" or \"price not dated\", come after the current ones, and are not compared. Absent on a row a provider answered just now." - changed
Output schema / properties / comparison / items / properties / unitPrice / descriptionPrevious value: -"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit."New value: +"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. Across sizes, value is compared on these, not on the prices: a smaller size is not cheaper because its price is lower. It reads beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit." - changed
Output schema / properties / comparison / items / properties / url / descriptionPrevious value: -"WEM tracked link to the retailer. Send the user here — WEM never takes payment."New value: +"WEM tracked link to the retailer page for this offer. WEM never takes payment." - changed
Output schema / properties / disclosure / descriptionPrevious value: -"Disclosure to relay once per answer, verbatim. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. Never substitute the version you saw last time — a row marked `affiliate: false` earns WEM nothing, and saying otherwise misdescribes it to the shopper."New value: +"WEM’s affiliate disclosure for this answer, written to be quoted as it is. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. A version from an earlier answer may not fit this one: a row marked `affiliate: false` earns WEM nothing."
- Changed
find_lowest_price41 fields changed- added
Input schema / properties / conditionAdded value: +{ + "description": "Same effect as include_used: \"any\", \"used\" or \"refurbished\" also includes used and refurbished listings; any other value means new only.", + "type": "string" +} - changed
Input schema / properties / max_price / descriptionPrevious value: -"Budget cap (GBP)"New value: +"Budget cap, in `currency`." - changed
Input schema / properties / priorities / descriptionPrevious value: -"What matters most (in order of importance)"New value: +"What matters most, in order. cheapest: lowest price. best_rated: higher rating. free_shipping: free delivery. fastest: states a delivery estimate. Weighed only where listings carry those details." - changed
Input schema / properties / query / descriptionPrevious value: -"Product name, barcode, ASIN, WEM ID, or wem3.ai/pl URL. A specific model should prefer compare_offers; this still resolves one if the host sends it here."New value: +"One kind of product or product: a name, barcode, ASIN, WEM ID or wem3.ai/pl URL. A single query, not a list." - changed
Output schema / descriptionPrevious value: -"A null `recommendation` with `coverage.kind` marketplace_only still has listings in `alternatives` — give those links. A null with no alternatives is a genuine miss. Never soften a genuine miss into a suggestion."New value: +"A null `recommendation` with `coverage.kind` marketplace_only still has listings in `alternatives`. A null with no alternatives is a genuine miss. A genuine miss is not a suggestion." - changed
Output schema / properties / alternatives / items / properties / affiliate / descriptionPrevious value: -"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. It is still a real offer, and its link is not affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` states whether all, some or none of the links are tracked." - changed
Output schema / properties / alternatives / items / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. Do not present a marketplace cluster as competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / alternatives / items / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: the note stands in place of a figure." - changed
Output schema / properties / alternatives / items / properties / priceNote / descriptionPrevious value: -"Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now."New value: +"Present only when `price` is null: the words that stand in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now." - changed
Output schema / properties / alternatives / items / properties / priceQualifier / descriptionPrevious value: -"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. Quote it as \"from £X\", never as the price or the cheapest. Absent means the price is firm for the row as described."New value: +"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. It reads as \"from £X\"; it is not the item's price or the cheapest. Absent means the price is firm for the row as described." - changed
Output schema / properties / alternatives / items / properties / priceStatus / descriptionPrevious value: -"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now."New value: +"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Those two read as \"last seen £X on 8 Sep\" or \"price not dated\", come after the current ones, and are not compared. Absent on a row a provider answered just now." - changed
Output schema / properties / alternatives / items / properties / unitPrice / descriptionPrevious value: -"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit."New value: +"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. Across sizes, value is compared on these, not on the prices: a smaller size is not cheaper because its price is lower. It reads beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit." - changed
Output schema / properties / alternatives / items / properties / url / descriptionPrevious value: -"WEM tracked link to the retailer. Send the user here — WEM never takes payment."New value: +"WEM tracked link to the retailer page for this offer. WEM never takes payment." - changed
Output schema / properties / catalogMatch / properties / identity / descriptionPrevious value: -"How the shopper’s words reached this product. Decides how you describe the match: on `inferred`, say WEM matched it by name (not by barcode) and do not call the identity confirmed, even when `identityBasis` is `barcode`; on `exact`, the barcode itself resolved it."New value: +"How the shopper’s words reached this product. On `inferred`, WEM matched it by name (not by barcode) and the identity is not confirmed, even when `identityBasis` is `barcode`; on `exact`, the barcode itself resolved it." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / affiliate / descriptionPrevious value: -"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. It is still a real offer, and its link is not affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` states whether all, some or none of the links are tracked." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. Do not present a marketplace cluster as competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / lastSeenAt / descriptionPrevious value: -"When WEM last READ this price from the retailer or a datafeed — the same reading `priceAgeDays` counts from, so the two always agree. Null means WEM cannot date the price: say it is undated, never that it is current."New value: +"When WEM last READ this price from the retailer or a datafeed — the same reading `priceAgeDays` counts from, so the two always agree. Null means WEM cannot date the price: it is undated, not current." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: the note stands in place of a figure." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceAgeDays / descriptionPrevious value: -"Calendar days (UK time) since WEM last READ this price: 0 read today, 1 yesterday. Null means WEM cannot say. Report null as undated; never present it as current."New value: +"Calendar days (UK time) since WEM last READ this price: 0 read today, 1 yesterday. Null means WEM cannot say. Null is undated, not current." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceNote / descriptionPrevious value: -"Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now."New value: +"Present only when `price` is null: the words that stand in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceQualifier / descriptionPrevious value: -"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. Quote it as \"from £X\", never as the price or the cheapest. Absent means the price is firm for the row as described."New value: +"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. It reads as \"from £X\"; it is not the item's price or the cheapest. Absent means the price is firm for the row as described." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceRefresh / descriptionPrevious value: -"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `none` nothing on a schedule. `none` means the figure will not move on its own however long it sits — say so rather than quoting it flat, and date it with `priceAgeDays`."New value: +"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `none` nothing on a schedule. `none` means the figure will not move on its own however long it sits ; `priceAgeDays` dates it." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceStatus / descriptionPrevious value: -"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now."New value: +"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Those two read as \"last seen £X on 8 Sep\" or \"price not dated\", come after the current ones, and are not compared. Absent on a row a provider answered just now." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / unitPrice / descriptionPrevious value: -"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit."New value: +"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. Across sizes, value is compared on these, not on the prices: a smaller size is not cheaper because its price is lower. It reads beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / url / descriptionPrevious value: -"WEM tracked link to the retailer. Send the user here — WEM never takes payment."New value: +"WEM tracked link to the retailer page for this offer. WEM never takes payment." - changed
Output schema / properties / catalogMatch / properties / unpriced / descriptionPrevious value: -"Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. Give the link with `priceNote` (\"See price at Amazon\"). Never state, estimate or compare a price for one, never call it the cheapest, and never count it in a lowest price or a saving."New value: +"Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. The row carries `priceNote` (e.g. \"See price at Amazon\") in place of a figure. No price is stated, estimated or compared for one; it is not the cheapest and is not counted in a lowest price or a saving." - changed
Output schema / properties / catalogMatch / properties / unpriced / items / properties / priceNote / descriptionPrevious value: -"What to show where a price would be, e.g. \"See price at Amazon\"."New value: +"What stands where a price would be, e.g. \"See price at Amazon\"." - changed
Output schema / properties / catalogMatch / properties / unpriced / items / properties / url / descriptionPrevious value: -"WEM tracked link. Relay it exactly."New value: +"WEM tracked link. The full URL; a shortened form is a different link." - changed
Output schema / properties / coverage / descriptionPrevious value: -"Present when surviving rows include a marketplace cluster at similar prices. That is not a retail floor — do not name the cheapest marketplace listing as the deal. The listings are still in the payload; give the user those links. If `next` points at the Chrome extension, send the shopper there for shops WEM does not yet hold as partners."New value: +"Present when surviving rows include a marketplace cluster at similar prices. That is not a retail floor — the cheapest marketplace listing is not the deal. The listings stay in the payload, each with its url. `next`, when present, is the Chrome extension page for shops WEM does not yet hold as partners." - changed
Output schema / properties / degraded / descriptionPrevious value: -"Present when this call hit its time budget and skipped enrichment. The offers returned are COMPLETE — only the extras were dropped. Do not report a missing catalogue block or missing observed retailers as WEM holding nothing, and do not retry automatically."New value: +"Present when this call hit its time budget and skipped enrichment. The offers returned are COMPLETE — only the extras were dropped. A missing catalogue block or missing observed retailers does not mean WEM holds nothing, and no retry is needed." - changed
Output schema / properties / disclosure / descriptionPrevious value: -"Disclosure to relay once per answer, verbatim. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. Never substitute the version you saw last time — a row marked `affiliate: false` earns WEM nothing, and saying otherwise misdescribes it to the shopper."New value: +"WEM’s affiliate disclosure for this answer, written to be quoted as it is. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. A version from an earlier answer may not fit this one: a row marked `affiliate: false` earns WEM nothing." - changed
Output schema / properties / next / descriptionPrevious value: -"Where to send the shopper when WEM's set is thin. chrome_extension means compare the same product on any retailer page — WEM shows that price even without an affiliate programme."New value: +"Present when WEM's set of offers is thin. chrome_extension is a page that compares the same product on any retailer page, including shops without an affiliate programme." - changed
Output schema / properties / recommendation / properties / affiliate / descriptionPrevious value: -"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. It is still a real offer, and its link is not affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` states whether all, some or none of the links are tracked." - changed
Output schema / properties / recommendation / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. Do not present a marketplace cluster as competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / recommendation / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: the note stands in place of a figure." - changed
Output schema / properties / recommendation / properties / priceNote / descriptionPrevious value: -"Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now."New value: +"Present only when `price` is null: the words that stand in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now." - changed
Output schema / properties / recommendation / properties / priceQualifier / descriptionPrevious value: -"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. Quote it as \"from £X\", never as the price or the cheapest. Absent means the price is firm for the row as described."New value: +"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. It reads as \"from £X\"; it is not the item's price or the cheapest. Absent means the price is firm for the row as described." - changed
Output schema / properties / recommendation / properties / priceStatus / descriptionPrevious value: -"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now."New value: +"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Those two read as \"last seen £X on 8 Sep\" or \"price not dated\", come after the current ones, and are not compared. Absent on a row a provider answered just now." - changed
Output schema / properties / recommendation / properties / unitPrice / descriptionPrevious value: -"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit."New value: +"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. Across sizes, value is compared on these, not on the prices: a smaller size is not cheaper because its price is lower. It reads beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit." - changed
Output schema / properties / recommendation / properties / url / descriptionPrevious value: -"WEM tracked link to the retailer. Send the user here — WEM never takes payment."New value: +"WEM tracked link to the retailer page for this offer. WEM never takes payment." - changed
Output schema / properties / search / descriptionPrevious value: -"Present when this result names no offer. GIVE THE USER THIS LINK — it is the answer when WEM has nothing else to say, and `markdown` is ready to paste. WEM searches retailers live on that page, including shops it holds no affiliate programme with, so an empty or withheld result here is not evidence the product is unavailable or unpriced."New value: +"Present when this result names no offer. `url` is WEM's results page for the query and `markdown` is the same link, pre-formatted. WEM searches retailers live on that page, including shops it holds no affiliate programme with, so an empty or withheld result here is not evidence the product is unavailable or unpriced."
- Changed
get_evidence_receipt1 field changed- changed
Input schema / properties / id / descriptionPrevious value: -"Receipt id, as returned on verify_offer as receipt.id (wem-evr-...)."New value: +"Receipt id (wem-evr- followed by 32 hex characters), as returned in a verify_offer result's receipt.id."
- Changed
get_product11 fields changed- changed
Input schema / properties / product_id / descriptionPrevious value: -"Product ID from search results"New value: +"The listing's `id` from the search result." - changed
Input schema / properties / provider / descriptionPrevious value: -"Provider name (e.g. \"ebay\", \"awin\")"New value: +"Retailer source of the listing, as given in the search result (e.g. \"ebay\", \"awin\")." - changed
Output schema / properties / affiliate / descriptionPrevious value: -"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. It is still a real offer, and its link is not affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` states whether all, some or none of the links are tracked." - changed
Output schema / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. Do not present a marketplace cluster as competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / disclosure / descriptionPrevious value: -"Disclosure to relay once per answer, verbatim. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. Never substitute the version you saw last time — a row marked `affiliate: false` earns WEM nothing, and saying otherwise misdescribes it to the shopper."New value: +"WEM’s affiliate disclosure for this answer, written to be quoted as it is. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. A version from an earlier answer may not fit this one: a row marked `affiliate: false` earns WEM nothing." - changed
Output schema / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: the note stands in place of a figure." - changed
Output schema / properties / priceNote / descriptionPrevious value: -"Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now."New value: +"Present only when `price` is null: the words that stand in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now." - changed
Output schema / properties / priceQualifier / descriptionPrevious value: -"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. Quote it as \"from £X\", never as the price or the cheapest. Absent means the price is firm for the row as described."New value: +"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. It reads as \"from £X\"; it is not the item's price or the cheapest. Absent means the price is firm for the row as described." - changed
Output schema / properties / priceStatus / descriptionPrevious value: -"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now."New value: +"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Those two read as \"last seen £X on 8 Sep\" or \"price not dated\", come after the current ones, and are not compared. Absent on a row a provider answered just now." - changed
Output schema / properties / unitPrice / descriptionPrevious value: -"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit."New value: +"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. Across sizes, value is compared on these, not on the prices: a smaller size is not cheaper because its price is lower. It reads beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit." - changed
Output schema / properties / url / descriptionPrevious value: -"WEM tracked link to the retailer. Send the user here — WEM never takes payment."New value: +"WEM tracked link to the retailer page for this offer. WEM never takes payment."
- Changed
lookup_products3 fields changed- changed
Output schema / properties / disclosure / descriptionPrevious value: -"Disclosure to relay once per answer, verbatim. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. Never substitute the version you saw last time — a row marked `affiliate: false` earns WEM nothing, and saying otherwise misdescribes it to the shopper."New value: +"WEM’s affiliate disclosure for this answer, written to be quoted as it is. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. A version from an earlier answer may not fit this one: a row marked `affiliate: false` earns WEM nothing." - changed
Output schema / properties / results / items / properties / product / properties / url / descriptionPrevious value: -"WEM product page listing every retailer WEM holds. Relay it exactly."New value: +"WEM product page listing every retailer WEM holds. The full URL; a shortened form is a different link." - changed
Output schema / properties / results / items / properties / status / descriptionPrevious value: -"not_found: WEM does not hold it yet — never say the product does not exist or has no price; look it up with compare_offers or search_products first. not_checked: not reached in this call, and not a miss. unrecognised: not an identifier this tool reads (product names go to compare_offers)."New value: +"not_found: WEM does not hold it yet — that is not a finding that the product does not exist or has no price. compare_offers and search_products are the lookups for it. not_checked: not reached in this call, and not a miss. unrecognised: not an identifier this tool reads (product names go to compare_offers)."
- Changed
search_products56 fields changed- changed
Input schema / properties / category / descriptionPrevious value: -"Filter by category (electronics, fashion, beauty, home, sports, collectibles)"New value: +"Optional. Keeps only live retailer listings whose own category name matches this text exactly; catalogue matches ignore it. Leave it out unless the shopper names a retailer's category." - added
Input schema / properties / currencyAdded value: +{ + "description": "ISO 4217 code for the shopper's market. Default GBP. Results and price filters use this currency.", + "type": "string" +} - changed
Input schema / properties / gtin / descriptionPrevious value: -"Product barcode (EAN/UPC/GTIN) when the host already has one. Feed rows are matched on this before title."New value: +"A product barcode (EAN/UPC/GTIN) the host already has. When given, retailer sources are searched by this barcode instead of by the query words." - changed
Input schema / properties / limit / descriptionPrevious value: -"Max results to return (default 10, max 30)"New value: +"How many listings to request from each retailer source (default 10, max 30). The combined list can hold more." - changed
Input schema / properties / max_price / descriptionPrevious value: -"Maximum price filter (GBP)"New value: +"Highest price to include, in `currency`. Applies to retailer listings, not to `catalogMatch`." - changed
Input schema / properties / min_price / descriptionPrevious value: -"Minimum price filter (GBP)"New value: +"Lowest price to include, in `currency`. Applies to retailer listings, not to `catalogMatch`." - changed
Input schema / properties / providers / descriptionPrevious value: -"Limit to specific providers (e.g. [\"ebay\", \"awin\"]). Omit for all."New value: +"Retailer sources to search live, e.g. [\"ebay\", \"awin\"]. Omit for all. Catalogue matches are not limited by it." - changed
Input schema / properties / query / descriptionPrevious value: -"Product name, barcode (EAN/UPC/GTIN), ASIN, MPN, merchant SKU, WEM ID, wem3.ai/pl URL, or comma-separated IDs of those kinds."New value: +"A product name, or an identifier: barcode (EAN/UPC/GTIN), ASIN, MPN, merchant SKU, WEM ID or wem3.ai/pl URL. Several identifiers may be comma-separated." - changed
Input schema / properties / sort_by / descriptionPrevious value: -"Sort order for results"New value: +"Order of the live retailer listings (default relevance). Not applied when the query identifies a product." - changed
Output schema / properties / catalogMatch / properties / identity / descriptionPrevious value: -"How the shopper’s words reached this product. Decides how you describe the match: on `inferred`, say WEM matched it by name (not by barcode) and do not call the identity confirmed, even when `identityBasis` is `barcode`; on `exact`, the barcode itself resolved it."New value: +"How the shopper’s words reached this product. On `inferred`, WEM matched it by name (not by barcode) and the identity is not confirmed, even when `identityBasis` is `barcode`; on `exact`, the barcode itself resolved it." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / affiliate / descriptionPrevious value: -"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. It is still a real offer, and its link is not affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` states whether all, some or none of the links are tracked." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. Do not present a marketplace cluster as competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / lastSeenAt / descriptionPrevious value: -"When WEM last READ this price from the retailer or a datafeed — the same reading `priceAgeDays` counts from, so the two always agree. Null means WEM cannot date the price: say it is undated, never that it is current."New value: +"When WEM last READ this price from the retailer or a datafeed — the same reading `priceAgeDays` counts from, so the two always agree. Null means WEM cannot date the price: it is undated, not current." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: the note stands in place of a figure." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceAgeDays / descriptionPrevious value: -"Calendar days (UK time) since WEM last READ this price: 0 read today, 1 yesterday. Null means WEM cannot say. Report null as undated; never present it as current."New value: +"Calendar days (UK time) since WEM last READ this price: 0 read today, 1 yesterday. Null means WEM cannot say. Null is undated, not current." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceNote / descriptionPrevious value: -"Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now."New value: +"Present only when `price` is null: the words that stand in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceQualifier / descriptionPrevious value: -"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. Quote it as \"from £X\", never as the price or the cheapest. Absent means the price is firm for the row as described."New value: +"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. It reads as \"from £X\"; it is not the item's price or the cheapest. Absent means the price is firm for the row as described." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceRefresh / descriptionPrevious value: -"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `none` nothing on a schedule. `none` means the figure will not move on its own however long it sits — say so rather than quoting it flat, and date it with `priceAgeDays`."New value: +"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `none` nothing on a schedule. `none` means the figure will not move on its own however long it sits ; `priceAgeDays` dates it." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceStatus / descriptionPrevious value: -"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now."New value: +"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Those two read as \"last seen £X on 8 Sep\" or \"price not dated\", come after the current ones, and are not compared. Absent on a row a provider answered just now." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / unitPrice / descriptionPrevious value: -"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit."New value: +"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. Across sizes, value is compared on these, not on the prices: a smaller size is not cheaper because its price is lower. It reads beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / url / descriptionPrevious value: -"WEM tracked link to the retailer. Send the user here — WEM never takes payment."New value: +"WEM tracked link to the retailer page for this offer. WEM never takes payment." - changed
Output schema / properties / catalogMatch / properties / unpriced / descriptionPrevious value: -"Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. Give the link with `priceNote` (\"See price at Amazon\"). Never state, estimate or compare a price for one, never call it the cheapest, and never count it in a lowest price or a saving."New value: +"Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. The row carries `priceNote` (e.g. \"See price at Amazon\") in place of a figure. No price is stated, estimated or compared for one; it is not the cheapest and is not counted in a lowest price or a saving." - changed
Output schema / properties / catalogMatch / properties / unpriced / items / properties / priceNote / descriptionPrevious value: -"What to show where a price would be, e.g. \"See price at Amazon\"."New value: +"What stands where a price would be, e.g. \"See price at Amazon\"." - changed
Output schema / properties / catalogMatch / properties / unpriced / items / properties / url / descriptionPrevious value: -"WEM tracked link. Relay it exactly."New value: +"WEM tracked link. The full URL; a shortened form is a different link." - changed
Output schema / properties / catalogMatches / items / properties / identity / descriptionPrevious value: -"How the shopper’s words reached this product. Decides how you describe the match: on `inferred`, say WEM matched it by name (not by barcode) and do not call the identity confirmed, even when `identityBasis` is `barcode`; on `exact`, the barcode itself resolved it."New value: +"How the shopper’s words reached this product. On `inferred`, WEM matched it by name (not by barcode) and the identity is not confirmed, even when `identityBasis` is `barcode`; on `exact`, the barcode itself resolved it." - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / affiliate / descriptionPrevious value: -"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. It is still a real offer, and its link is not affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` states whether all, some or none of the links are tracked." - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. Do not present a marketplace cluster as competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / lastSeenAt / descriptionPrevious value: -"When WEM last READ this price from the retailer or a datafeed — the same reading `priceAgeDays` counts from, so the two always agree. Null means WEM cannot date the price: say it is undated, never that it is current."New value: +"When WEM last READ this price from the retailer or a datafeed — the same reading `priceAgeDays` counts from, so the two always agree. Null means WEM cannot date the price: it is undated, not current." - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: the note stands in place of a figure." - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / priceAgeDays / descriptionPrevious value: -"Calendar days (UK time) since WEM last READ this price: 0 read today, 1 yesterday. Null means WEM cannot say. Report null as undated; never present it as current."New value: +"Calendar days (UK time) since WEM last READ this price: 0 read today, 1 yesterday. Null means WEM cannot say. Null is undated, not current." - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / priceNote / descriptionPrevious value: -"Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now."New value: +"Present only when `price` is null: the words that stand in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now." - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / priceQualifier / descriptionPrevious value: -"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. Quote it as \"from £X\", never as the price or the cheapest. Absent means the price is firm for the row as described."New value: +"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. It reads as \"from £X\"; it is not the item's price or the cheapest. Absent means the price is firm for the row as described." - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / priceRefresh / descriptionPrevious value: -"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `none` nothing on a schedule. `none` means the figure will not move on its own however long it sits — say so rather than quoting it flat, and date it with `priceAgeDays`."New value: +"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `none` nothing on a schedule. `none` means the figure will not move on its own however long it sits ; `priceAgeDays` dates it." - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / priceStatus / descriptionPrevious value: -"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now."New value: +"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Those two read as \"last seen £X on 8 Sep\" or \"price not dated\", come after the current ones, and are not compared. Absent on a row a provider answered just now." - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / unitPrice / descriptionPrevious value: -"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit."New value: +"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. Across sizes, value is compared on these, not on the prices: a smaller size is not cheaper because its price is lower. It reads beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit." - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / url / descriptionPrevious value: -"WEM tracked link to the retailer. Send the user here — WEM never takes payment."New value: +"WEM tracked link to the retailer page for this offer. WEM never takes payment." - changed
Output schema / properties / catalogMatches / items / properties / unpriced / descriptionPrevious value: -"Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. Give the link with `priceNote` (\"See price at Amazon\"). Never state, estimate or compare a price for one, never call it the cheapest, and never count it in a lowest price or a saving."New value: +"Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. The row carries `priceNote` (e.g. \"See price at Amazon\") in place of a figure. No price is stated, estimated or compared for one; it is not the cheapest and is not counted in a lowest price or a saving." - changed
Output schema / properties / catalogMatches / items / properties / unpriced / items / properties / priceNote / descriptionPrevious value: -"What to show where a price would be, e.g. \"See price at Amazon\"."New value: +"What stands where a price would be, e.g. \"See price at Amazon\"." - changed
Output schema / properties / catalogMatches / items / properties / unpriced / items / properties / url / descriptionPrevious value: -"WEM tracked link. Relay it exactly."New value: +"WEM tracked link. The full URL; a shortened form is a different link." - changed
Output schema / properties / coverage / descriptionPrevious value: -"Present when surviving rows include a marketplace cluster at similar prices. That is not a retail floor — do not name the cheapest marketplace listing as the deal. The listings are still in the payload; give the user those links. If `next` points at the Chrome extension, send the shopper there for shops WEM does not yet hold as partners."New value: +"Present when surviving rows include a marketplace cluster at similar prices. That is not a retail floor — the cheapest marketplace listing is not the deal. The listings stay in the payload, each with its url. `next`, when present, is the Chrome extension page for shops WEM does not yet hold as partners." - changed
Output schema / properties / degraded / descriptionPrevious value: -"Present when this call hit its time budget and skipped enrichment. The offers returned are COMPLETE — only the extras were dropped. Do not report a missing catalogue block or missing observed retailers as WEM holding nothing, and do not retry automatically."New value: +"Present when this call hit its time budget and skipped enrichment. The offers returned are COMPLETE — only the extras were dropped. A missing catalogue block or missing observed retailers does not mean WEM holds nothing, and no retry is needed." - changed
Output schema / properties / disclosure / descriptionPrevious value: -"Disclosure to relay once per answer, verbatim. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. Never substitute the version you saw last time — a row marked `affiliate: false` earns WEM nothing, and saying otherwise misdescribes it to the shopper."New value: +"WEM’s affiliate disclosure for this answer, written to be quoted as it is. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. A version from an earlier answer may not fit this one: a row marked `affiliate: false` earns WEM nothing." - changed
Output schema / properties / next / descriptionPrevious value: -"Where to send the shopper when WEM's set is thin. chrome_extension means compare the same product on any retailer page — WEM shows that price even without an affiliate programme."New value: +"Present when WEM's set of offers is thin. chrome_extension is a page that compares the same product on any retailer page, including shops without an affiliate programme." - changed
Output schema / properties / products / items / properties / affiliate / descriptionPrevious value: -"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. It is still a real offer, and its link is not affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` states whether all, some or none of the links are tracked." - changed
Output schema / properties / products / items / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. Do not present a marketplace cluster as competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / products / items / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: the note stands in place of a figure." - changed
Output schema / properties / products / items / properties / priceNote / descriptionPrevious value: -"Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now."New value: +"Present only when `price` is null: the words that stand in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now." - changed
Output schema / properties / products / items / properties / priceQualifier / descriptionPrevious value: -"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. Quote it as \"from £X\", never as the price or the cheapest. Absent means the price is firm for the row as described."New value: +"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. It reads as \"from £X\"; it is not the item's price or the cheapest. Absent means the price is firm for the row as described." - changed
Output schema / properties / products / items / properties / priceStatus / descriptionPrevious value: -"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now."New value: +"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Those two read as \"last seen £X on 8 Sep\" or \"price not dated\", come after the current ones, and are not compared. Absent on a row a provider answered just now." - changed
Output schema / properties / products / items / properties / unitPrice / descriptionPrevious value: -"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit."New value: +"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. Across sizes, value is compared on these, not on the prices: a smaller size is not cheaper because its price is lower. It reads beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit." - changed
Output schema / properties / products / items / properties / url / descriptionPrevious value: -"WEM tracked link to the retailer. Send the user here — WEM never takes payment."New value: +"WEM tracked link to the retailer page for this offer. WEM never takes payment." - changed
Output schema / properties / search / descriptionPrevious value: -"Present when this result names no offer. GIVE THE USER THIS LINK — it is the answer when WEM has nothing else to say, and `markdown` is ready to paste. WEM searches retailers live on that page, including shops it holds no affiliate programme with, so an empty or withheld result here is not evidence the product is unavailable or unpriced."New value: +"Present when this result names no offer. `url` is WEM's results page for the query and `markdown` is the same link, pre-formatted. WEM searches retailers live on that page, including shops it holds no affiliate programme with, so an empty or withheld result here is not evidence the product is unavailable or unpriced." - changed
Output schema / properties / sizeSpread / descriptionPrevious value: -"Present when the returned rows are different sizes and the query named none, so price ordering is meaningless: the cheapest row is cheapest because it is less of the product. Do NOT name a cheapest, a lowest price, or a best deal across these rows. State the size beside every price and ask the shopper which size they want. Where rows carry `unitPrice`, that is the like-for-like figure: quote it, and rank on it if the shopper asks which is better value. The rows are real — give the user those links."New value: +"Present when the returned rows are different sizes and the query named none, so price ordering is meaningless: the cheapest row is cheapest because it is less of the product. Do NOT name a cheapest, a lowest price, or a best deal across these rows. The size belongs beside every price. Where rows carry `unitPrice`, that is the like-for-like figure, and it is the figure to rank on when the question is which is better value. The rows are real listings, each with its url." - changed
Output schema / properties / unpriced / descriptionPrevious value: -"Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. Give the link with `priceNote` (\"See price at Amazon\"). Never state, estimate or compare a price for one, never call it the cheapest, and never count it in a lowest price or a saving."New value: +"Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. The row carries `priceNote` (e.g. \"See price at Amazon\") in place of a figure. No price is stated, estimated or compared for one; it is not the cheapest and is not counted in a lowest price or a saving." - changed
Output schema / properties / unpriced / items / properties / priceNote / descriptionPrevious value: -"What to show where a price would be, e.g. \"See price at Amazon\"."New value: +"What stands where a price would be, e.g. \"See price at Amazon\"." - changed
Output schema / properties / unpriced / items / properties / url / descriptionPrevious value: -"WEM tracked link. Relay it exactly."New value: +"WEM tracked link. The full URL; a shortened form is a different link."
- Changed
search_promotions5 fields changed- changed
Input schema / properties / currency / descriptionPrevious value: -"ISO 4217 code for the shopper's market: GBP (default) or USD. Promotions are regional, so this decides which retailers' offers are read."New value: +"ISO 4217 code for the shopper's market: GBP (default) or USD. Promotions are regional, so this decides which market's offers are read." - changed
Output schema / properties / disclosure / descriptionPrevious value: -"Disclosure to relay once per answer, verbatim. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. Never substitute the version you saw last time — a row marked `affiliate: false` earns WEM nothing, and saying otherwise misdescribes it to the shopper."New value: +"WEM’s affiliate disclosure for this answer, written to be quoted as it is. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. A version from an earlier answer may not fit this one: a row marked `affiliate: false` earns WEM nothing." - changed
Output schema / properties / promotions / items / properties / url / descriptionPrevious value: -"WEM tracked redirect to the retailer’s promotion page. Relay it exactly; never rewrite it."New value: +"WEM tracked redirect to the retailer’s promotion page. The full URL; a shortened or rewritten form is a different link." - changed
Output schema / properties / search / descriptionPrevious value: -"Present when this result names no offer. GIVE THE USER THIS LINK — it is the answer when WEM has nothing else to say, and `markdown` is ready to paste. WEM searches retailers live on that page, including shops it holds no affiliate programme with, so an empty or withheld result here is not evidence the product is unavailable or unpriced."New value: +"Present when this result names no offer. `url` is WEM's results page for the query and `markdown` is the same link, pre-formatted. WEM searches retailers live on that page, including shops it holds no affiliate programme with, so an empty or withheld result here is not evidence the product is unavailable or unpriced." - changed
Output schema / properties / withheld / descriptionPrevious value: -"Matching promotions WEM did not show, by reason. codeNotPermitted and mentionsCode mean a checkout code WEM may not publish: the code may well exist — never say there is none."New value: +"Matching promotions WEM did not show, counted by reason: notPublishable (a checkout code or offer the retailer’s programme does not let WEM publish; the code may well exist), notJoined, notActive, outsideMarket, noTrackedLink, otherPublisherLink, incompleteRecord."
- Changed
semantic_search32 fields changed- changed
Input schema / properties / category / descriptionPrevious value: -"Optional category filter"New value: +"Optional. Keeps only products whose feed category matches this text exactly." - changed
Input schema / properties / description / descriptionPrevious value: -"Natural language description of what the user is looking for"New value: +"Plain-language description of what the shopper needs." - changed
Input schema / properties / limit / descriptionPrevious value: -"Max results (default 10, max 20)"New value: +"Max products to return (default 10, max 20)." - changed
Input schema / properties / max_price / descriptionPrevious value: -"Maximum price (GBP)"New value: +"Optional upper price bound, compared with each product's listed price (currencies are not converted)." - changed
Input schema / properties / min_price / descriptionPrevious value: -"Minimum price (GBP)"New value: +"Optional lower price bound, compared with each product's listed price (currencies are not converted)." - added
Input schema / properties / providerAdded value: +{ + "description": "Optional. Keeps only products from this partner feed, e.g. \"awin\".", + "type": "string" +} - changed
Output schema / properties / catalogMatch / properties / identity / descriptionPrevious value: -"How the shopper’s words reached this product. Decides how you describe the match: on `inferred`, say WEM matched it by name (not by barcode) and do not call the identity confirmed, even when `identityBasis` is `barcode`; on `exact`, the barcode itself resolved it."New value: +"How the shopper’s words reached this product. On `inferred`, WEM matched it by name (not by barcode) and the identity is not confirmed, even when `identityBasis` is `barcode`; on `exact`, the barcode itself resolved it." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / affiliate / descriptionPrevious value: -"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. It is still a real offer, and its link is not affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` states whether all, some or none of the links are tracked." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. Do not present a marketplace cluster as competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / lastSeenAt / descriptionPrevious value: -"When WEM last READ this price from the retailer or a datafeed — the same reading `priceAgeDays` counts from, so the two always agree. Null means WEM cannot date the price: say it is undated, never that it is current."New value: +"When WEM last READ this price from the retailer or a datafeed — the same reading `priceAgeDays` counts from, so the two always agree. Null means WEM cannot date the price: it is undated, not current." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: the note stands in place of a figure." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceAgeDays / descriptionPrevious value: -"Calendar days (UK time) since WEM last READ this price: 0 read today, 1 yesterday. Null means WEM cannot say. Report null as undated; never present it as current."New value: +"Calendar days (UK time) since WEM last READ this price: 0 read today, 1 yesterday. Null means WEM cannot say. Null is undated, not current." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceNote / descriptionPrevious value: -"Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now."New value: +"Present only when `price` is null: the words that stand in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceQualifier / descriptionPrevious value: -"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. Quote it as \"from £X\", never as the price or the cheapest. Absent means the price is firm for the row as described."New value: +"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. It reads as \"from £X\"; it is not the item's price or the cheapest. Absent means the price is firm for the row as described." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceRefresh / descriptionPrevious value: -"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `none` nothing on a schedule. `none` means the figure will not move on its own however long it sits — say so rather than quoting it flat, and date it with `priceAgeDays`."New value: +"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `none` nothing on a schedule. `none` means the figure will not move on its own however long it sits ; `priceAgeDays` dates it." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceStatus / descriptionPrevious value: -"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now."New value: +"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Those two read as \"last seen £X on 8 Sep\" or \"price not dated\", come after the current ones, and are not compared. Absent on a row a provider answered just now." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / unitPrice / descriptionPrevious value: -"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit."New value: +"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. Across sizes, value is compared on these, not on the prices: a smaller size is not cheaper because its price is lower. It reads beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / url / descriptionPrevious value: -"WEM tracked link to the retailer. Send the user here — WEM never takes payment."New value: +"WEM tracked link to the retailer page for this offer. WEM never takes payment." - changed
Output schema / properties / catalogMatch / properties / unpriced / descriptionPrevious value: -"Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. Give the link with `priceNote` (\"See price at Amazon\"). Never state, estimate or compare a price for one, never call it the cheapest, and never count it in a lowest price or a saving."New value: +"Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. The row carries `priceNote` (e.g. \"See price at Amazon\") in place of a figure. No price is stated, estimated or compared for one; it is not the cheapest and is not counted in a lowest price or a saving." - changed
Output schema / properties / catalogMatch / properties / unpriced / items / properties / priceNote / descriptionPrevious value: -"What to show where a price would be, e.g. \"See price at Amazon\"."New value: +"What stands where a price would be, e.g. \"See price at Amazon\"." - changed
Output schema / properties / catalogMatch / properties / unpriced / items / properties / url / descriptionPrevious value: -"WEM tracked link. Relay it exactly."New value: +"WEM tracked link. The full URL; a shortened form is a different link." - changed
Output schema / properties / disclosure / descriptionPrevious value: -"Disclosure to relay once per answer, verbatim. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. Never substitute the version you saw last time — a row marked `affiliate: false` earns WEM nothing, and saying otherwise misdescribes it to the shopper."New value: +"WEM’s affiliate disclosure for this answer, written to be quoted as it is. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. A version from an earlier answer may not fit this one: a row marked `affiliate: false` earns WEM nothing." - changed
Output schema / properties / next / descriptionPrevious value: -"Where to send the shopper when WEM's set is thin. chrome_extension means compare the same product on any retailer page — WEM shows that price even without an affiliate programme."New value: +"Present when WEM's set of offers is thin. chrome_extension is a page that compares the same product on any retailer page, including shops without an affiliate programme." - changed
Output schema / properties / products / items / properties / affiliate / descriptionPrevious value: -"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. It is still a real offer, and its link is not affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` states whether all, some or none of the links are tracked." - changed
Output schema / properties / products / items / properties / channel / descriptionPrevious value: -"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. Do not present a marketplace cluster as competing authorised retailers."New value: +"retailer is a named shop (Boots, Currys). marketplace is eBay/AliExpress/Temu-style parallel listings. A marketplace cluster is not a set of competing authorised retailers." - changed
Output schema / properties / products / items / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: the note stands in place of a figure." - changed
Output schema / properties / products / items / properties / priceNote / descriptionPrevious value: -"Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now."New value: +"Present only when `price` is null: the words that stand in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now." - changed
Output schema / properties / products / items / properties / priceQualifier / descriptionPrevious value: -"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. Quote it as \"from £X\", never as the price or the cheapest. Absent means the price is firm for the row as described."New value: +"Present when `price` is the OPENING price of a range, not the price of this item: a multi-variation listing where the seller advertises its cheapest variant and the shopper picks a size on the page. It reads as \"from £X\"; it is not the item's price or the cheapest. Absent means the price is firm for the row as described." - changed
Output schema / properties / products / items / properties / priceStatus / descriptionPrevious value: -"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now."New value: +"`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Those two read as \"last seen £X on 8 Sep\" or \"price not dated\", come after the current ones, and are not compared. Absent on a row a provider answered just now." - changed
Output schema / properties / products / items / properties / unitPrice / descriptionPrevious value: -"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit."New value: +"Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. Across sizes, value is compared on these, not on the prices: a smaller size is not cheaper because its price is lower. It reads beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit." - changed
Output schema / properties / products / items / properties / url / descriptionPrevious value: -"WEM tracked link to the retailer. Send the user here — WEM never takes payment."New value: +"WEM tracked link to the retailer page for this offer. WEM never takes payment." - changed
Output schema / properties / search / descriptionPrevious value: -"Present when this result names no offer. GIVE THE USER THIS LINK — it is the answer when WEM has nothing else to say, and `markdown` is ready to paste. WEM searches retailers live on that page, including shops it holds no affiliate programme with, so an empty or withheld result here is not evidence the product is unavailable or unpriced."New value: +"Present when this result names no offer. `url` is WEM's results page for the query and `markdown` is the same link, pre-formatted. WEM searches retailers live on that page, including shops it holds no affiliate programme with, so an empty or withheld result here is not evidence the product is unavailable or unpriced."
- Changed
verify_offer14 fields changed- changed
Input schema / properties / currency / descriptionPrevious value: -"ISO 4217 code for the claimed price. Default GBP."New value: +"ISO 4217 code for the claimed price. Default GBP. Only offers in this currency are compared." - changed
Input schema / properties / externalId / descriptionPrevious value: -"The retailer's own product id (ASIN, eBay item number). Use with provider."New value: +"That listing's own id (ASIN, eBay item number). Use with provider." - changed
Input schema / properties / price / descriptionPrevious value: -"The price being claimed. Omit to ask only what the verified offers are."New value: +"The price being claimed. Omit to ask only for the observed offers." - changed
Input schema / properties / provider / descriptionPrevious value: -"Retailer slug for the listing being checked, e.g. 'currys'."New value: +"With externalId: the retailer source of a listing that identifies the product, e.g. 'amazon' or 'ebay'. To name the shop the claim is about, use `retailer`." - changed
Input schema / properties / retailer / descriptionPrevious value: -"Retailer the price was claimed at — slug or display name."New value: +"The shop the price was claimed at, as a slug or display name. Omit to compare against every shop." - changed
Input schema / properties / title / descriptionPrevious value: -"Product title. Weakest identifier — used only when no id is available."New value: +"Product title. The weakest identifier: used only when no id is given, and only if it passes a relevance check." - changed
Output schema / properties / cheapest / properties / affiliate / descriptionPrevious value: -"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. It is still a real offer, and its link is not affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` states whether all, some or none of the links are tracked." - changed
Output schema / properties / claimMatched / properties / affiliate / descriptionPrevious value: -"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. It is still a real offer, and its link is not affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` states whether all, some or none of the links are tracked." - changed
Output schema / properties / disclosure / descriptionPrevious value: -"Disclosure to relay once per answer, verbatim. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. Never substitute the version you saw last time — a row marked `affiliate: false` earns WEM nothing, and saying otherwise misdescribes it to the shopper."New value: +"WEM’s affiliate disclosure for this answer, written to be quoted as it is. Its wording changes with the rows: it states whether every outbound link is affiliate-tracked, only some are, or none are. A version from an earlier answer may not fit this one: a row marked `affiliate: false` earns WEM nothing." - changed
Output schema / properties / offers / items / properties / affiliate / descriptionPrevious value: -"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. It is still a real offer, and its link is not affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` states whether all, some or none of the links are tracked." - changed
Output schema / properties / sameModel / descriptionPrevious value: -"Present only when the maker's own page says another model code is this product and a person at WEM has checked it. These are NOT offers for the product asked about: never merge them into `offers`, never call one this product's lowest price or the best deal. On verify_offer they are not part of the check: `verdict`, `cheapest`, `betterBy`, `summary` and the receipt are about the product asked about, and a cheaper sister code never makes the claimed price wrong. Mention it as a separate line: quote `summary`, name the maker's page (`maker.host`) as the source, and link `url`, WEM's comparison for that model, not a shop. When `relation` is `differs`, name the `differences` and never call its price a saving. Absent is not evidence that no equivalent exists."New value: +"Present only when the maker's own page says another model code is this product and a person at WEM has checked it. These are NOT offers for the product asked about: they are not part of `offers`, and none is this product's lowest price or the best deal. On verify_offer they are not part of the check: `verdict`, `cheapest`, `betterBy`, `summary` and the receipt are about the product asked about, and a cheaper sister code never makes the claimed price wrong. `summary` is written to be quoted as it is. `maker.host` is the source of the claim. `url` is WEM's comparison for that model, not a shop. When `relation` is `differs`, the `differences` are what the maker says differs, and its price is not a saving. Absent is not evidence that no equivalent exists." - changed
Output schema / properties / sameModel / items / properties / cheapest / descriptionPrevious value: -"The other model's cheapest named shop. Null when no named shop has an in-stock price for it. Give its age; never present it as current without one."New value: +"The other model's cheapest named shop. Null when no named shop has an in-stock price for it. `priceAgeDays` gives its age; without one it is not current." - changed
Output schema / properties / sameModel / items / properties / maker / descriptionPrevious value: -"The maker's own page that says so: the proof. Cite it; WEM is not the source of the claim."New value: +"The maker's own page that says so: the proof. WEM is not the source of the claim." - changed
Output schema / properties / sameModel / items / properties / url / descriptionPrevious value: -"WEM's comparison for that model. Link this, not a shop."New value: +"WEM's comparison for that model, not a shop."
1 tool update
- Changed
compare_offers2 fields changed- changed
Input schema / properties / currency / descriptionPrevious value: -"ISO 4217 code for the shopper's market. Default GBP. Decides which retailers are searched, not just how the answer reads — pass it explicitly, because WEM does not infer the market from IP. When WEM holds the product only in another currency it says so rather than presenting a foreign listing as the answer."New value: +"ISO 4217 code for the shopper's market. Default GBP. Decides which market's offers WEM returns from its catalogue, not just how the answer reads — pass it explicitly, because WEM does not infer the market from IP. When WEM holds the product only in another currency it says so rather than presenting a foreign listing as the answer." - changed
Output schema / properties / links / descriptionPrevious value: -"The tracked links from `offers`, cheapest first, pre-formatted to quote. Give these to the user when you name an offer: they carry the attribution WEM is funded by, and a retailer URL you compose yourself does not. Present even when the host renders a WEM card — never assume the card reached the user."New value: +"The links from `offers`, cheapest first, pre-formatted to quote. Each opens the retailer’s page for the offer WEM priced; a retailer URL found elsewhere may be a different listing or price. State them in text even when the host renders a WEM card: the card may not reach the user."
7 tool updates
- Changed
compare_offers13 fields changed- added
Output schema / properties / highPrice / descriptionAdded value: +"Highest current price in `offers`; null with lowPrice." - changed
Output schema / properties / links / items / properties / currency / typePrevious value: -"string"New value: +[ + "string", + "null" +] - added
Output schema / properties / links / items / properties / price / descriptionAdded value: +"Null for a listing in `unpriced`: its markdown says \"see price at Amazon\", and so must you." - changed
Output schema / properties / links / items / properties / price / typePrevious value: -"number"New value: +[ + "number", + "null" +] - added
Output schema / properties / lowPrice / descriptionAdded value: +"Lowest CURRENT price in `offers` (read within 14 days). Null when no price is current or WEM holds none it may quote — never fill it from a stale or undated row, or from `unpriced`." - changed
Output schema / properties / offers / descriptionPrevious value: -"Ascending by price. Barcode, slug and WEM ID rows are the product. A title match is inferred — check identity.strength before stating it as exact."New value: +"Current prices first (`priceStatus`), each group ascending by price; a stale or undated row is listed, never compared. Barcode, slug and WEM ID rows are the product. A title match is inferred — check identity.strength before stating it as exact." - changed
Output schema / properties / offers / items / properties / lastSeenAt / descriptionPrevious value: -"When WEM last VISITED this offer row — not when it read the price. The refresh sweep touches this even when the retailer lookup fails, so it is not evidence the price is current. Use `priceAgeDays` to date a price; never this."New value: +"When WEM last READ this price from the retailer or a datafeed — the same reading `priceAgeDays` counts from, so the two always agree. Null means WEM cannot date the price: say it is undated, never that it is current." - changed
Output schema / properties / offers / items / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own." - changed
Output schema / properties / offers / items / properties / price / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / properties / offers / items / properties / priceAgeDays / descriptionPrevious value: -"Whole days since WEM last actually READ this price from the retailer or a datafeed. Null means WEM cannot say — common and correct for Amazon, whose licence caps price retention at 24 hours. Report null as undated; never present it as current."New value: +"Calendar days (UK time) since WEM last READ this price: 0 read today, 1 yesterday. Null means WEM cannot say. Report null as undated; never present it as current." - added
Output schema / properties / offers / items / properties / priceNoteAdded value: +{ + "description": "Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now.", + "type": "string" +} - added
Output schema / properties / offers / items / properties / priceStatusAdded value: +{ + "description": "`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now.", + "enum": [ + "current", + "stale", + "undated" + ], + "type": "string" +} - added
Output schema / properties / unpricedAdded value: +{ + "description": "Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. Give the link with `priceNote` (\"See price at Amazon\"). Never state, estimate or compare a price for one, never call it the cheapest, and never count it in a lowest price or a saving.", + "items": { + "properties": { + "channel": { + "enum": [ + "retailer", + "marketplace" + ], + "type": "string" + }, + "id": { + "type": "string" + }, + "priceNote": { + "description": "What to show where a price would be, e.g. \"See price at Amazon\".", + "type": "string" + }, + "provider": { + "type": "string" + }, + "title": { + "type": "string" + }, + "url": { + "description": "WEM tracked link. Relay it exactly.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +}
- Changed
compare_products4 fields changed- changed
Output schema / properties / comparison / items / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own." - changed
Output schema / properties / comparison / items / properties / price / typePrevious value: -"number"New value: +[ + "number", + "null" +] - added
Output schema / properties / comparison / items / properties / priceNoteAdded value: +{ + "description": "Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now.", + "type": "string" +} - added
Output schema / properties / comparison / items / properties / priceStatusAdded value: +{ + "description": "`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now.", + "enum": [ + "current", + "stale", + "undated" + ], + "type": "string" +}
- Changed
find_lowest_price16 fields changed- changed
Output schema / properties / alternatives / items / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own." - changed
Output schema / properties / alternatives / items / properties / price / typePrevious value: -"number"New value: +[ + "number", + "null" +] - added
Output schema / properties / alternatives / items / properties / priceNoteAdded value: +{ + "description": "Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now.", + "type": "string" +} - added
Output schema / properties / alternatives / items / properties / priceStatusAdded value: +{ + "description": "`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now.", + "enum": [ + "current", + "stale", + "undated" + ], + "type": "string" +} - added
Output schema / properties / catalogMatch / properties / lowPrice / descriptionAdded value: +"Lowest CURRENT price in `offers` (priceStatus `current`). Null when none is current: never fill it from an older or undated row." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / lastSeenAt / descriptionPrevious value: -"When WEM last VISITED this offer row — not when it read the price. The refresh sweep touches this even when the retailer lookup fails, so it is not evidence the price is current. Use `priceAgeDays` to date a price; never this."New value: +"When WEM last READ this price from the retailer or a datafeed — the same reading `priceAgeDays` counts from, so the two always agree. Null means WEM cannot date the price: say it is undated, never that it is current." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / price / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceAgeDays / descriptionPrevious value: -"Whole days since WEM last actually READ this price from the retailer or a datafeed. Null means WEM cannot say — common and correct for Amazon, whose licence caps price retention at 24 hours. Report null as undated; never present it as current."New value: +"Calendar days (UK time) since WEM last READ this price: 0 read today, 1 yesterday. Null means WEM cannot say. Report null as undated; never present it as current." - added
Output schema / properties / catalogMatch / properties / offers / items / properties / priceNoteAdded value: +{ + "description": "Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now.", + "type": "string" +} - added
Output schema / properties / catalogMatch / properties / offers / items / properties / priceStatusAdded value: +{ + "description": "`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now.", + "enum": [ + "current", + "stale", + "undated" + ], + "type": "string" +} - added
Output schema / properties / catalogMatch / properties / unpricedAdded value: +{ + "description": "Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. Give the link with `priceNote` (\"See price at Amazon\"). Never state, estimate or compare a price for one, never call it the cheapest, and never count it in a lowest price or a saving.", + "items": { + "properties": { + "channel": { + "enum": [ + "retailer", + "marketplace" + ], + "type": "string" + }, + "id": { + "type": "string" + }, + "priceNote": { + "description": "What to show where a price would be, e.g. \"See price at Amazon\".", + "type": "string" + }, + "provider": { + "type": "string" + }, + "title": { + "type": "string" + }, + "url": { + "description": "WEM tracked link. Relay it exactly.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / recommendation / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own." - changed
Output schema / properties / recommendation / properties / price / typePrevious value: -"number"New value: +[ + "number", + "null" +] - added
Output schema / properties / recommendation / properties / priceNoteAdded value: +{ + "description": "Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now.", + "type": "string" +} - added
Output schema / properties / recommendation / properties / priceStatusAdded value: +{ + "description": "`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now.", + "enum": [ + "current", + "stale", + "undated" + ], + "type": "string" +}
- Changed
get_product4 fields changed- changed
Output schema / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own." - changed
Output schema / properties / price / typePrevious value: -"number"New value: +[ + "number", + "null" +] - added
Output schema / properties / priceNoteAdded value: +{ + "description": "Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now.", + "type": "string" +} - added
Output schema / properties / priceStatusAdded value: +{ + "description": "`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now.", + "enum": [ + "current", + "stale", + "undated" + ], + "type": "string" +}
- Changed
lookup_products1 field changed- changed
Output schema / properties / results / items / properties / lowPrice / descriptionPrevious value: -"Lowest indicative price at a named retailer in `currency`. Null when WEM holds the product only in another currency (see heldInCurrencies) — never convert one yourself — or only as marketplace listings."New value: +"Lowest current indicative price (read within 14 days) at a named retailer in `currency`. Null when WEM holds the product only in another currency (see heldInCurrencies) — never convert one yourself — only as marketplace listings, or with no current price (see note)."
- Changed
search_products21 fields changed- added
Output schema / properties / catalogMatch / properties / lowPrice / descriptionAdded value: +"Lowest CURRENT price in `offers` (priceStatus `current`). Null when none is current: never fill it from an older or undated row." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / lastSeenAt / descriptionPrevious value: -"When WEM last VISITED this offer row — not when it read the price. The refresh sweep touches this even when the retailer lookup fails, so it is not evidence the price is current. Use `priceAgeDays` to date a price; never this."New value: +"When WEM last READ this price from the retailer or a datafeed — the same reading `priceAgeDays` counts from, so the two always agree. Null means WEM cannot date the price: say it is undated, never that it is current." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / price / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceAgeDays / descriptionPrevious value: -"Whole days since WEM last actually READ this price from the retailer or a datafeed. Null means WEM cannot say — common and correct for Amazon, whose licence caps price retention at 24 hours. Report null as undated; never present it as current."New value: +"Calendar days (UK time) since WEM last READ this price: 0 read today, 1 yesterday. Null means WEM cannot say. Report null as undated; never present it as current." - added
Output schema / properties / catalogMatch / properties / offers / items / properties / priceNoteAdded value: +{ + "description": "Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now.", + "type": "string" +} - added
Output schema / properties / catalogMatch / properties / offers / items / properties / priceStatusAdded value: +{ + "description": "`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now.", + "enum": [ + "current", + "stale", + "undated" + ], + "type": "string" +} - added
Output schema / properties / catalogMatch / properties / unpricedAdded value: +{ + "description": "Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. Give the link with `priceNote` (\"See price at Amazon\"). Never state, estimate or compare a price for one, never call it the cheapest, and never count it in a lowest price or a saving.", + "items": { + "properties": { + "channel": { + "enum": [ + "retailer", + "marketplace" + ], + "type": "string" + }, + "id": { + "type": "string" + }, + "priceNote": { + "description": "What to show where a price would be, e.g. \"See price at Amazon\".", + "type": "string" + }, + "provider": { + "type": "string" + }, + "title": { + "type": "string" + }, + "url": { + "description": "WEM tracked link. Relay it exactly.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / catalogMatches / items / properties / lowPrice / descriptionAdded value: +"Lowest CURRENT price in `offers` (priceStatus `current`). Null when none is current: never fill it from an older or undated row." - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / lastSeenAt / descriptionPrevious value: -"When WEM last VISITED this offer row — not when it read the price. The refresh sweep touches this even when the retailer lookup fails, so it is not evidence the price is current. Use `priceAgeDays` to date a price; never this."New value: +"When WEM last READ this price from the retailer or a datafeed — the same reading `priceAgeDays` counts from, so the two always agree. Null means WEM cannot date the price: say it is undated, never that it is current." - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own." - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / price / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / priceAgeDays / descriptionPrevious value: -"Whole days since WEM last actually READ this price from the retailer or a datafeed. Null means WEM cannot say — common and correct for Amazon, whose licence caps price retention at 24 hours. Report null as undated; never present it as current."New value: +"Calendar days (UK time) since WEM last READ this price: 0 read today, 1 yesterday. Null means WEM cannot say. Report null as undated; never present it as current." - added
Output schema / properties / catalogMatches / items / properties / offers / items / properties / priceNoteAdded value: +{ + "description": "Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now.", + "type": "string" +} - added
Output schema / properties / catalogMatches / items / properties / offers / items / properties / priceStatusAdded value: +{ + "description": "`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now.", + "enum": [ + "current", + "stale", + "undated" + ], + "type": "string" +} - added
Output schema / properties / catalogMatches / items / properties / unpricedAdded value: +{ + "description": "Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. Give the link with `priceNote` (\"See price at Amazon\"). Never state, estimate or compare a price for one, never call it the cheapest, and never count it in a lowest price or a saving.", + "items": { + "properties": { + "channel": { + "enum": [ + "retailer", + "marketplace" + ], + "type": "string" + }, + "id": { + "type": "string" + }, + "priceNote": { + "description": "What to show where a price would be, e.g. \"See price at Amazon\".", + "type": "string" + }, + "provider": { + "type": "string" + }, + "title": { + "type": "string" + }, + "url": { + "description": "WEM tracked link. Relay it exactly.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / products / items / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own." - changed
Output schema / properties / products / items / properties / price / typePrevious value: -"number"New value: +[ + "number", + "null" +] - added
Output schema / properties / products / items / properties / priceNoteAdded value: +{ + "description": "Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now.", + "type": "string" +} - added
Output schema / properties / products / items / properties / priceStatusAdded value: +{ + "description": "`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now.", + "enum": [ + "current", + "stale", + "undated" + ], + "type": "string" +} - added
Output schema / properties / unpricedAdded value: +{ + "description": "Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. Give the link with `priceNote` (\"See price at Amazon\"). Never state, estimate or compare a price for one, never call it the cheapest, and never count it in a lowest price or a saving.", + "items": { + "properties": { + "channel": { + "enum": [ + "retailer", + "marketplace" + ], + "type": "string" + }, + "id": { + "type": "string" + }, + "priceNote": { + "description": "What to show where a price would be, e.g. \"See price at Amazon\".", + "type": "string" + }, + "provider": { + "type": "string" + }, + "title": { + "type": "string" + }, + "url": { + "description": "WEM tracked link. Relay it exactly.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +}
- Changed
semantic_search12 fields changed- added
Output schema / properties / catalogMatch / properties / lowPrice / descriptionAdded value: +"Lowest CURRENT price in `offers` (priceStatus `current`). Null when none is current: never fill it from an older or undated row." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / lastSeenAt / descriptionPrevious value: -"When WEM last VISITED this offer row — not when it read the price. The refresh sweep touches this even when the retailer lookup fails, so it is not evidence the price is current. Use `priceAgeDays` to date a price; never this."New value: +"When WEM last READ this price from the retailer or a datafeed — the same reading `priceAgeDays` counts from, so the two always agree. Null means WEM cannot date the price: say it is undated, never that it is current." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / price / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceAgeDays / descriptionPrevious value: -"Whole days since WEM last actually READ this price from the retailer or a datafeed. Null means WEM cannot say — common and correct for Amazon, whose licence caps price retention at 24 hours. Report null as undated; never present it as current."New value: +"Calendar days (UK time) since WEM last READ this price: 0 read today, 1 yesterday. Null means WEM cannot say. Report null as undated; never present it as current." - added
Output schema / properties / catalogMatch / properties / offers / items / properties / priceNoteAdded value: +{ + "description": "Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now.", + "type": "string" +} - added
Output schema / properties / catalogMatch / properties / offers / items / properties / priceStatusAdded value: +{ + "description": "`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now.", + "enum": [ + "current", + "stale", + "undated" + ], + "type": "string" +} - added
Output schema / properties / catalogMatch / properties / unpricedAdded value: +{ + "description": "Listings whose price WEM may not show — today, Amazon rows Amazon’s API did not price just now. Give the link with `priceNote` (\"See price at Amazon\"). Never state, estimate or compare a price for one, never call it the cheapest, and never count it in a lowest price or a saving.", + "items": { + "properties": { + "channel": { + "enum": [ + "retailer", + "marketplace" + ], + "type": "string" + }, + "id": { + "type": "string" + }, + "priceNote": { + "description": "What to show where a price would be, e.g. \"See price at Amazon\".", + "type": "string" + }, + "provider": { + "type": "string" + }, + "title": { + "type": "string" + }, + "url": { + "description": "WEM tracked link. Relay it exactly.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / products / items / properties / price / descriptionPrevious value: -"Indicative price. The retailer sets the final price at checkout."New value: +"Indicative price. The retailer sets the final price at checkout. Null, with `priceNote`, when WEM may not show this listing’s price: show the note and the link, never a figure of your own." - changed
Output schema / properties / products / items / properties / price / typePrevious value: -"number"New value: +[ + "number", + "null" +] - added
Output schema / properties / products / items / properties / priceNoteAdded value: +{ + "description": "Present only when `price` is null: the words to show in its place, e.g. \"See price at Amazon\". An Amazon price is shown only when Amazon’s API supplied it just now.", + "type": "string" +} - added
Output schema / properties / products / items / properties / priceStatusAdded value: +{ + "description": "`current`: WEM read this price within the last 14 days; only a current price may lead, be called the cheapest or lowest, be compared or enter a saving. `stale`: read longer ago. `undated`: WEM cannot say when. Show those two as \"last seen £X on 8 Sep\" or \"price not dated\", after the current ones, and never compare them. Absent on a row a provider answered just now.", + "enum": [ + "current", + "stale", + "undated" + ], + "type": "string" +}
7 tool updates
- Changed
compare_offers2 fields changed- added
Output schema / properties / filteredAdded value: +{ + "additionalProperties": { + "type": "number" + }, + "description": "Offers of this product WEM held back, tallied by reason. \"Priced far below this product’s other offers\" is a marketplace listing under 40% of what the product sells for elsewhere — the shape of a counterfeit, a part or a mislisted variant. Those prices are not in `offers`, `lowPrice`, `links`, `summary` or `priceHistory.low`: never quote one as the cheapest, a deal or the 90-day low. Say how many were held back.", + "type": [ + "object", + "null" + ] +} - changed
Output schema / properties / offers / items / properties / affiliate / descriptionPrevious value: -"False when this is a retailer page WEM observed without a programme. Still a real listing; the click is not commission-bearing. Absent means the usual partner path."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."
- Changed
compare_products1 field changed- changed
Output schema / properties / comparison / items / properties / affiliate / descriptionPrevious value: -"False when this is a retailer page WEM observed without a programme. Still a real listing; the click is not commission-bearing. Absent means the usual partner path."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."
- Changed
find_lowest_price4 fields changed- changed
Output schema / properties / alternatives / items / properties / affiliate / descriptionPrevious value: -"False when this is a retailer page WEM observed without a programme. Still a real listing; the click is not commission-bearing. Absent means the usual partner path."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / affiliate / descriptionPrevious value: -"False when this is a retailer page WEM observed without a programme. Still a real listing; the click is not commission-bearing. Absent means the usual partner path."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording." - changed
Output schema / properties / filtered / descriptionPrevious value: -"Withheld candidates tallied by reason (e.g. accessories, wrong model). Report this count rather than implying the search was exhaustive."New value: +"Withheld candidates tallied by reason (e.g. accessories, another model, a bundle or multipack, a replica, a listing priced far below the product’s other offers). Report this count rather than implying the search was exhaustive, and never quote a withheld listing’s price as the cheapest or as a deal." - changed
Output schema / properties / recommendation / properties / affiliate / descriptionPrevious value: -"False when this is a retailer page WEM observed without a programme. Still a real listing; the click is not commission-bearing. Absent means the usual partner path."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."
- Changed
get_product1 field changed- changed
Output schema / properties / affiliate / descriptionPrevious value: -"False when this is a retailer page WEM observed without a programme. Still a real listing; the click is not commission-bearing. Absent means the usual partner path."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."
- Changed
search_products4 fields changed- changed
Output schema / properties / catalogMatch / properties / offers / items / properties / affiliate / descriptionPrevious value: -"False when this is a retailer page WEM observed without a programme. Still a real listing; the click is not commission-bearing. Absent means the usual partner path."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording." - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / affiliate / descriptionPrevious value: -"False when this is a retailer page WEM observed without a programme. Still a real listing; the click is not commission-bearing. Absent means the usual partner path."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording." - changed
Output schema / properties / filtered / descriptionPrevious value: -"Withheld candidates tallied by reason (e.g. accessories, wrong model). Report this count rather than implying the search was exhaustive."New value: +"Withheld candidates tallied by reason (e.g. accessories, another model, a bundle or multipack, a replica, a listing priced far below the product’s other offers). Report this count rather than implying the search was exhaustive, and never quote a withheld listing’s price as the cheapest or as a deal." - changed
Output schema / properties / products / items / properties / affiliate / descriptionPrevious value: -"False when this is a retailer page WEM observed without a programme. Still a real listing; the click is not commission-bearing. Absent means the usual partner path."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."
- Changed
semantic_search3 fields changed- changed
Output schema / properties / catalogMatch / properties / offers / items / properties / affiliate / descriptionPrevious value: -"False when this is a retailer page WEM observed without a programme. Still a real listing; the click is not commission-bearing. Absent means the usual partner path."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording." - changed
Output schema / properties / filtered / descriptionPrevious value: -"Withheld candidates tallied by reason (e.g. accessories, wrong model). Report this count rather than implying the search was exhaustive."New value: +"Withheld candidates tallied by reason (e.g. accessories, another model, a bundle or multipack, a replica, a listing priced far below the product’s other offers). Report this count rather than implying the search was exhaustive, and never quote a withheld listing’s price as the cheapest or as a deal." - changed
Output schema / properties / products / items / properties / affiliate / descriptionPrevious value: -"False when this is a retailer page WEM observed without a programme. Still a real listing; the click is not commission-bearing. Absent means the usual partner path."New value: +"False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording."
- Changed
verify_offer3 fields changed- added
Output schema / properties / cheapest / properties / affiliateAdded value: +{ + "description": "False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording.", + "type": "boolean" +} - added
Output schema / properties / claimMatched / properties / affiliateAdded value: +{ + "description": "False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording.", + "type": "boolean" +} - added
Output schema / properties / offers / items / properties / affiliateAdded value: +{ + "description": "False when this link earns WEM nothing: the shop has no affiliate programme with WEM, or this link does not carry one. Still a real offer: list it with the others, and never call its link affiliate-tracked. Absent (or true) means the link is affiliate-tracked. `disclosure` already states whether all, some or none of the links are tracked; relay that rather than your own wording.", + "type": "boolean" +}
1 tool update
- Changed
verify_offer1 field changed- added
Output schema / properties / offers / descriptionAdded value: +"Prices WEM holds for this product, including indicative ones and shops it has no affiliate programme with yet. When `cheapest` is null, still show these rows and their links: they are a comparison, not a verification. Do not call them confirmed, and do not name a verified cheapest."
4 tool updates
- Changed
compare_offers2 fields changed- changed
Output schema / properties / offers / items / properties / priceRefresh / descriptionPrevious value: -"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `crawl` WEM reading the retailer’s own public product page, `none` nothing at all. `none` means the figure is frozen at whatever seeded it and will not move however long it sits — say so rather than quoting it flat. A `crawl` price was observed on the retailer’s page rather than supplied by them, so date it with `priceAgeDays` and expect `affiliate: false` unless a programme also exists."New value: +"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `none` nothing on a schedule. `none` means the figure will not move on its own however long it sits — say so rather than quoting it flat, and date it with `priceAgeDays`." - changed
Output schema / properties / offers / items / properties / priceRefresh / enumPrevious value: -[ - "live-api", - "feed", - "crawl", - "none" -]New value: +[ + "live-api", + "feed", + "none" +]
- Changed
find_lowest_price2 fields changed- changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceRefresh / descriptionPrevious value: -"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `crawl` WEM reading the retailer’s own public product page, `none` nothing at all. `none` means the figure is frozen at whatever seeded it and will not move however long it sits — say so rather than quoting it flat. A `crawl` price was observed on the retailer’s page rather than supplied by them, so date it with `priceAgeDays` and expect `affiliate: false` unless a programme also exists."New value: +"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `none` nothing on a schedule. `none` means the figure will not move on its own however long it sits — say so rather than quoting it flat, and date it with `priceAgeDays`." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceRefresh / enumPrevious value: -[ - "live-api", - "feed", - "crawl", - "none" -]New value: +[ + "live-api", + "feed", + "none" +]
- Changed
search_products4 fields changed- changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceRefresh / descriptionPrevious value: -"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `crawl` WEM reading the retailer’s own public product page, `none` nothing at all. `none` means the figure is frozen at whatever seeded it and will not move however long it sits — say so rather than quoting it flat. A `crawl` price was observed on the retailer’s page rather than supplied by them, so date it with `priceAgeDays` and expect `affiliate: false` unless a programme also exists."New value: +"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `none` nothing on a schedule. `none` means the figure will not move on its own however long it sits — say so rather than quoting it flat, and date it with `priceAgeDays`." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceRefresh / enumPrevious value: -[ - "live-api", - "feed", - "crawl", - "none" -]New value: +[ + "live-api", + "feed", + "none" +] - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / priceRefresh / descriptionPrevious value: -"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `crawl` WEM reading the retailer’s own public product page, `none` nothing at all. `none` means the figure is frozen at whatever seeded it and will not move however long it sits — say so rather than quoting it flat. A `crawl` price was observed on the retailer’s page rather than supplied by them, so date it with `priceAgeDays` and expect `affiliate: false` unless a programme also exists."New value: +"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `none` nothing on a schedule. `none` means the figure will not move on its own however long it sits — say so rather than quoting it flat, and date it with `priceAgeDays`." - changed
Output schema / properties / catalogMatches / items / properties / offers / items / properties / priceRefresh / enumPrevious value: -[ - "live-api", - "feed", - "crawl", - "none" -]New value: +[ + "live-api", + "feed", + "none" +]
- Changed
semantic_search2 fields changed- changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceRefresh / descriptionPrevious value: -"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `crawl` WEM reading the retailer’s own public product page, `none` nothing at all. `none` means the figure is frozen at whatever seeded it and will not move however long it sits — say so rather than quoting it flat. A `crawl` price was observed on the retailer’s page rather than supplied by them, so date it with `priceAgeDays` and expect `affiliate: false` unless a programme also exists."New value: +"What re-reads this retailer’s prices: `live-api` a product-lookup API, `feed` a partner datafeed, `none` nothing on a schedule. `none` means the figure will not move on its own however long it sits — say so rather than quoting it flat, and date it with `priceAgeDays`." - changed
Output schema / properties / catalogMatch / properties / offers / items / properties / priceRefresh / enumPrevious value: -[ - "live-api", - "feed", - "crawl", - "none" -]New value: +[ + "live-api", + "feed", + "none" +]
2 tool updates
- Changed
compare_offers1 field changed- changed
Output schema / properties / sameModel / descriptionPrevious value: -"Present only when the maker's own page says another model code is this product and a person at WEM has checked it. These are NOT offers for the product asked about: never merge them into `offers`, never call one this product's lowest price or the best deal, and never let one change a verify_offer verdict. Mention it as a separate line: quote `summary`, name the maker's page (`maker.host`) as the source, and link `url`, WEM's comparison for that model, not a shop. When `relation` is `differs`, name the `differences` and never call its price a saving. Absent means WEM holds no checked equivalent, not that none exists."New value: +"Present only when the maker's own page says another model code is this product and a person at WEM has checked it. These are NOT offers for the product asked about: never merge them into `offers`, never call one this product's lowest price or the best deal. On verify_offer they are not part of the check: `verdict`, `cheapest`, `betterBy`, `summary` and the receipt are about the product asked about, and a cheaper sister code never makes the claimed price wrong. Mention it as a separate line: quote `summary`, name the maker's page (`maker.host`) as the source, and link `url`, WEM's comparison for that model, not a shop. When `relation` is `differs`, name the `differences` and never call its price a saving. Absent is not evidence that no equivalent exists."
- Changed
verify_offer1 field changed- added
Output schema / properties / sameModelAdded value: +{ + "description": "Present only when the maker's own page says another model code is this product and a person at WEM has checked it. These are NOT offers for the product asked about: never merge them into `offers`, never call one this product's lowest price or the best deal. On verify_offer they are not part of the check: `verdict`, `cheapest`, `betterBy`, `summary` and the receipt are about the product asked about, and a cheaper sister code never makes the claimed price wrong. Mention it as a separate line: quote `summary`, name the maker's page (`maker.host`) as the source, and link `url`, WEM's comparison for that model, not a shop. When `relation` is `differs`, name the `differences` and never call its price a saving. Absent is not evidence that no equivalent exists.", + "items": { + "properties": { + "cheapest": { + "description": "The other model's cheapest named shop. Null when no named shop has an in-stock price for it. Give its age; never present it as current without one.", + "properties": { + "currency": { + "type": "string" + }, + "price": { + "type": "number" + }, + "priceAgeDays": { + "description": "Days since WEM read that price. Null means undated.", + "type": [ + "number", + "null" + ] + }, + "shop": { + "type": "string" + } + }, + "type": [ + "object", + "null" + ] + }, + "checkedOn": { + "description": "When a person at WEM read the maker’s page (YYYY-MM-DD).", + "type": "string" + }, + "differences": { + "description": "What the maker says differs. Empty when identical.", + "items": { + "type": "string" + }, + "type": "array" + }, + "maker": { + "description": "The maker's own page that says so: the proof. Cite it; WEM is not the source of the claim.", + "properties": { + "host": { + "type": "string" + }, + "says": { + "description": "The page's words, as checked.", + "type": "string" + }, + "url": { + "type": "string" + } + }, + "type": "object" + }, + "model": { + "description": "The other model code, as the maker writes it.", + "type": "string" + }, + "relation": { + "description": "`identical`: the maker says it is the same product. `differs`: the same product except `differences`; not like for like.", + "enum": [ + "identical", + "differs" + ], + "type": "string" + }, + "summary": { + "description": "WEM’s words for it, written to be quoted as they are.", + "type": "string" + }, + "url": { + "description": "WEM's comparison for that model. Link this, not a shop.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "model", + "relation", + "differences", + "maker", + "checkedOn", + "summary" + ], + "type": "object" + }, + "type": "array" +}
1 tool update
- Changed
compare_offers1 field changed- added
Output schema / properties / sameModelAdded value: +{ + "description": "Present only when the maker's own page says another model code is this product and a person at WEM has checked it. These are NOT offers for the product asked about: never merge them into `offers`, never call one this product's lowest price or the best deal, and never let one change a verify_offer verdict. Mention it as a separate line: quote `summary`, name the maker's page (`maker.host`) as the source, and link `url`, WEM's comparison for that model, not a shop. When `relation` is `differs`, name the `differences` and never call its price a saving. Absent means WEM holds no checked equivalent, not that none exists.", + "items": { + "properties": { + "cheapest": { + "description": "The other model's cheapest named shop. Null when no named shop has an in-stock price for it. Give its age; never present it as current without one.", + "properties": { + "currency": { + "type": "string" + }, + "price": { + "type": "number" + }, + "priceAgeDays": { + "description": "Days since WEM read that price. Null means undated.", + "type": [ + "number", + "null" + ] + }, + "shop": { + "type": "string" + } + }, + "type": [ + "object", + "null" + ] + }, + "checkedOn": { + "description": "When a person at WEM read the maker’s page (YYYY-MM-DD).", + "type": "string" + }, + "differences": { + "description": "What the maker says differs. Empty when identical.", + "items": { + "type": "string" + }, + "type": "array" + }, + "maker": { + "description": "The maker's own page that says so: the proof. Cite it; WEM is not the source of the claim.", + "properties": { + "host": { + "type": "string" + }, + "says": { + "description": "The page's words, as checked.", + "type": "string" + }, + "url": { + "type": "string" + } + }, + "type": "object" + }, + "model": { + "description": "The other model code, as the maker writes it.", + "type": "string" + }, + "relation": { + "description": "`identical`: the maker says it is the same product. `differs`: the same product except `differences`; not like for like.", + "enum": [ + "identical", + "differs" + ], + "type": "string" + }, + "summary": { + "description": "WEM’s words for it, written to be quoted as they are.", + "type": "string" + }, + "url": { + "description": "WEM's comparison for that model. Link this, not a shop.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "model", + "relation", + "differences", + "maker", + "checkedOn", + "summary" + ], + "type": "object" + }, + "type": "array" +}
6 tool updates
- Changed
compare_offers1 field changed- added
Output schema / properties / offers / items / properties / unitPriceAdded value: +{ + "description": "Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit.", + "properties": { + "amount": { + "type": "number" + }, + "currency": { + "description": "ISO 4217 code.", + "type": "string" + }, + "per": { + "enum": [ + "100ml", + "litre", + "100g", + "kg", + "item" + ], + "type": "string" + } + }, + "type": "object" +}
- Changed
compare_products1 field changed- added
Output schema / properties / comparison / items / properties / unitPriceAdded value: +{ + "description": "Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit.", + "properties": { + "amount": { + "type": "number" + }, + "currency": { + "description": "ISO 4217 code.", + "type": "string" + }, + "per": { + "enum": [ + "100ml", + "litre", + "100g", + "kg", + "item" + ], + "type": "string" + } + }, + "type": "object" +}
- Changed
find_lowest_price3 fields changed- added
Output schema / properties / alternatives / items / properties / unitPriceAdded value: +{ + "description": "Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit.", + "properties": { + "amount": { + "type": "number" + }, + "currency": { + "description": "ISO 4217 code.", + "type": "string" + }, + "per": { + "enum": [ + "100ml", + "litre", + "100g", + "kg", + "item" + ], + "type": "string" + } + }, + "type": "object" +} - added
Output schema / properties / catalogMatch / properties / offers / items / properties / unitPriceAdded value: +{ + "description": "Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit.", + "properties": { + "amount": { + "type": "number" + }, + "currency": { + "description": "ISO 4217 code.", + "type": "string" + }, + "per": { + "enum": [ + "100ml", + "litre", + "100g", + "kg", + "item" + ], + "type": "string" + } + }, + "type": "object" +} - added
Output schema / properties / recommendation / properties / unitPriceAdded value: +{ + "description": "Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit.", + "properties": { + "amount": { + "type": "number" + }, + "currency": { + "description": "ISO 4217 code.", + "type": "string" + }, + "per": { + "enum": [ + "100ml", + "litre", + "100g", + "kg", + "item" + ], + "type": "string" + } + }, + "type": "object" +}
- Changed
get_product1 field changed- added
Output schema / properties / unitPriceAdded value: +{ + "description": "Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit.", + "properties": { + "amount": { + "type": "number" + }, + "currency": { + "description": "ISO 4217 code.", + "type": "string" + }, + "per": { + "enum": [ + "100ml", + "litre", + "100g", + "kg", + "item" + ], + "type": "string" + } + }, + "type": "object" +}
- Changed
search_products4 fields changed- added
Output schema / properties / catalogMatch / properties / offers / items / properties / unitPriceAdded value: +{ + "description": "Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit.", + "properties": { + "amount": { + "type": "number" + }, + "currency": { + "description": "ISO 4217 code.", + "type": "string" + }, + "per": { + "enum": [ + "100ml", + "litre", + "100g", + "kg", + "item" + ], + "type": "string" + } + }, + "type": "object" +} - added
Output schema / properties / catalogMatches / items / properties / offers / items / properties / unitPriceAdded value: +{ + "description": "Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit.", + "properties": { + "amount": { + "type": "number" + }, + "currency": { + "description": "ISO 4217 code.", + "type": "string" + }, + "per": { + "enum": [ + "100ml", + "litre", + "100g", + "kg", + "item" + ], + "type": "string" + } + }, + "type": "object" +} - added
Output schema / properties / products / items / properties / unitPriceAdded value: +{ + "description": "Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit.", + "properties": { + "amount": { + "type": "number" + }, + "currency": { + "description": "ISO 4217 code.", + "type": "string" + }, + "per": { + "enum": [ + "100ml", + "litre", + "100g", + "kg", + "item" + ], + "type": "string" + } + }, + "type": "object" +} - changed
Output schema / properties / sizeSpread / descriptionPrevious value: -"Present when the returned rows are different sizes and the query named none, so price ordering is meaningless: the cheapest row is cheapest because it is less of the product. Do NOT name a cheapest, a lowest price, or a best deal across these rows. State the size beside every price and ask the shopper which size they want. The rows are real — give the user those links."New value: +"Present when the returned rows are different sizes and the query named none, so price ordering is meaningless: the cheapest row is cheapest because it is less of the product. Do NOT name a cheapest, a lowest price, or a best deal across these rows. State the size beside every price and ask the shopper which size they want. Where rows carry `unitPrice`, that is the like-for-like figure: quote it, and rank on it if the shopper asks which is better value. The rows are real — give the user those links."
- Changed
semantic_search2 fields changed- added
Output schema / properties / catalogMatch / properties / offers / items / properties / unitPriceAdded value: +{ + "description": "Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit.", + "properties": { + "amount": { + "type": "number" + }, + "currency": { + "description": "ISO 4217 code.", + "type": "string" + }, + "per": { + "enum": [ + "100ml", + "litre", + "100g", + "kg", + "item" + ], + "type": "string" + } + }, + "type": "object" +} - added
Output schema / properties / products / items / properties / unitPriceAdded value: +{ + "description": "Price per 100ml, 100g, litre, kg or item, from the size this row's title states. Present only when the rows differ in size, in one unit across all of them, and only for things bought by the amount (beauty, food, supplements), never an appliance's capacity. When comparing value across sizes, compare these, never the prices: a smaller size is not cheaper because its price is lower. Quote it beside the price (\"£29.95, £99.83 per 100ml\"). Absent does not mean the price is per unit.", + "properties": { + "amount": { + "type": "number" + }, + "currency": { + "description": "ISO 4217 code.", + "type": "string" + }, + "per": { + "enum": [ + "100ml", + "litre", + "100g", + "kg", + "item" + ], + "type": "string" + } + }, + "type": "object" +}
4 tool updates
- Changed
compare_offers3 fields changed- changed
Output schema / properties / identity / descriptionPrevious value: -"How the product was identified. Never present a strength of \"inferred\" as a barcode-exact identity."New value: +"How the shopper’s words reached this product. Decides how you describe the match: on `inferred`, say WEM matched it by name (not by barcode) and do not call the identity confirmed, even when `identityBasis` is `barcode`; on `exact`, the barcode itself resolved it." - changed
Output schema / properties / identity / properties / strength / descriptionPrevious value: -"exact = barcode; catalogued = a WEM key or listing id; inferred = matched on the product name and still a guess."New value: +"exact = barcode; catalogued = a WEM key or listing id; inferred = matched on the product name, MPN or SKU and still a guess." - added
Output schema / properties / identityBasisAdded value: +{ + "description": "How this product’s offers are grouped — NOT how the shopper’s words found the product; that is `identity`. `barcode`: the product carries a GTIN, so every offer here is that same item. `curated-grouping`: it carries none, and the grouping is an inference. Never call a result a barcode match on the strength of this field: when `identity.strength` is `inferred`, say WEM matched the product by name.", + "enum": [ + "barcode", + "curated-grouping" + ], + "type": "string" +}
- Changed
find_lowest_price3 fields changed- changed
Output schema / properties / catalogMatch / descriptionPrevious value: -"Offers WEM holds under one catalogue product. Check `identityBasis`: on `barcode` these are resolved by GTIN rather than by matching titles, so prefer them and cite their prices over anything in `products`. On `curated-grouping` the product carries no barcode, the grouping is an inference like any title match, and a cheaper row in `products` may well be the same item — see `cheaperElsewhere`."New value: +"Offers WEM holds under one catalogue product. Check `identityBasis`: on `barcode` the product carries a GTIN and every offer here is that same item, so prefer them and cite their prices over anything in `products`. On `curated-grouping` the product carries no barcode, the grouping is an inference like any title match, and a cheaper row in `products` may well be the same item — see `cheaperElsewhere`. Whether the shopper’s words reached this product by barcode or by name is `identity`, a separate question: on `inferred`, say WEM matched it by name." - added
Output schema / properties / catalogMatch / properties / identityAdded value: +{ + "description": "How the shopper’s words reached this product. Decides how you describe the match: on `inferred`, say WEM matched it by name (not by barcode) and do not call the identity confirmed, even when `identityBasis` is `barcode`; on `exact`, the barcode itself resolved it.", + "properties": { + "method": { + "enum": [ + "gtin", + "slug", + "listing", + "title" + ], + "type": "string" + }, + "strength": { + "description": "exact = barcode; catalogued = a WEM key or listing id; inferred = matched on the product name, MPN or SKU and still a guess.", + "enum": [ + "exact", + "catalogued", + "inferred" + ], + "type": "string" + } + }, + "type": [ + "object", + "null" + ] +} - changed
Output schema / properties / catalogMatch / properties / identityBasis / descriptionPrevious value: -"What this block’s identity rests on. `barcode` — the canonical product carries a GTIN and these offers are the same physical item. `curated-grouping` — it carries none, so the grouping is an inference of the same kind a title match is; do not describe it to the user as barcode-confirmed, and do not let it outrank a cheaper row in `products` on price alone."New value: +"What this block’s identity rests on. `barcode` — the canonical product carries a GTIN and these offers are the same physical item. `curated-grouping` — it carries none, so the grouping is an inference of the same kind a title match is; do not describe it to the user as barcode-confirmed, and do not let it outrank a cheaper row in `products` on price alone. This is how the offers are grouped, not how the query matched the product — see `identity`."
- Changed
search_products6 fields changed- changed
Output schema / properties / catalogMatch / descriptionPrevious value: -"Offers WEM holds under one catalogue product. Check `identityBasis`: on `barcode` these are resolved by GTIN rather than by matching titles, so prefer them and cite their prices over anything in `products`. On `curated-grouping` the product carries no barcode, the grouping is an inference like any title match, and a cheaper row in `products` may well be the same item — see `cheaperElsewhere`."New value: +"Offers WEM holds under one catalogue product. Check `identityBasis`: on `barcode` the product carries a GTIN and every offer here is that same item, so prefer them and cite their prices over anything in `products`. On `curated-grouping` the product carries no barcode, the grouping is an inference like any title match, and a cheaper row in `products` may well be the same item — see `cheaperElsewhere`. Whether the shopper’s words reached this product by barcode or by name is `identity`, a separate question: on `inferred`, say WEM matched it by name." - added
Output schema / properties / catalogMatch / properties / identityAdded value: +{ + "description": "How the shopper’s words reached this product. Decides how you describe the match: on `inferred`, say WEM matched it by name (not by barcode) and do not call the identity confirmed, even when `identityBasis` is `barcode`; on `exact`, the barcode itself resolved it.", + "properties": { + "method": { + "enum": [ + "gtin", + "slug", + "listing", + "title" + ], + "type": "string" + }, + "strength": { + "description": "exact = barcode; catalogued = a WEM key or listing id; inferred = matched on the product name, MPN or SKU and still a guess.", + "enum": [ + "exact", + "catalogued", + "inferred" + ], + "type": "string" + } + }, + "type": [ + "object", + "null" + ] +} - changed
Output schema / properties / catalogMatch / properties / identityBasis / descriptionPrevious value: -"What this block’s identity rests on. `barcode` — the canonical product carries a GTIN and these offers are the same physical item. `curated-grouping` — it carries none, so the grouping is an inference of the same kind a title match is; do not describe it to the user as barcode-confirmed, and do not let it outrank a cheaper row in `products` on price alone."New value: +"What this block’s identity rests on. `barcode` — the canonical product carries a GTIN and these offers are the same physical item. `curated-grouping` — it carries none, so the grouping is an inference of the same kind a title match is; do not describe it to the user as barcode-confirmed, and do not let it outrank a cheaper row in `products` on price alone. This is how the offers are grouped, not how the query matched the product — see `identity`." - changed
Output schema / properties / catalogMatches / items / descriptionPrevious value: -"Offers WEM holds under one catalogue product. Check `identityBasis`: on `barcode` these are resolved by GTIN rather than by matching titles, so prefer them and cite their prices over anything in `products`. On `curated-grouping` the product carries no barcode, the grouping is an inference like any title match, and a cheaper row in `products` may well be the same item — see `cheaperElsewhere`."New value: +"Offers WEM holds under one catalogue product. Check `identityBasis`: on `barcode` the product carries a GTIN and every offer here is that same item, so prefer them and cite their prices over anything in `products`. On `curated-grouping` the product carries no barcode, the grouping is an inference like any title match, and a cheaper row in `products` may well be the same item — see `cheaperElsewhere`. Whether the shopper’s words reached this product by barcode or by name is `identity`, a separate question: on `inferred`, say WEM matched it by name." - added
Output schema / properties / catalogMatches / items / properties / identityAdded value: +{ + "description": "How the shopper’s words reached this product. Decides how you describe the match: on `inferred`, say WEM matched it by name (not by barcode) and do not call the identity confirmed, even when `identityBasis` is `barcode`; on `exact`, the barcode itself resolved it.", + "properties": { + "method": { + "enum": [ + "gtin", + "slug", + "listing", + "title" + ], + "type": "string" + }, + "strength": { + "description": "exact = barcode; catalogued = a WEM key or listing id; inferred = matched on the product name, MPN or SKU and still a guess.", + "enum": [ + "exact", + "catalogued", + "inferred" + ], + "type": "string" + } + }, + "type": [ + "object", + "null" + ] +} - changed
Output schema / properties / catalogMatches / items / properties / identityBasis / descriptionPrevious value: -"What this block’s identity rests on. `barcode` — the canonical product carries a GTIN and these offers are the same physical item. `curated-grouping` — it carries none, so the grouping is an inference of the same kind a title match is; do not describe it to the user as barcode-confirmed, and do not let it outrank a cheaper row in `products` on price alone."New value: +"What this block’s identity rests on. `barcode` — the canonical product carries a GTIN and these offers are the same physical item. `curated-grouping` — it carries none, so the grouping is an inference of the same kind a title match is; do not describe it to the user as barcode-confirmed, and do not let it outrank a cheaper row in `products` on price alone. This is how the offers are grouped, not how the query matched the product — see `identity`."
- Changed
semantic_search3 fields changed- changed
Output schema / properties / catalogMatch / descriptionPrevious value: -"Offers WEM holds under one catalogue product. Check `identityBasis`: on `barcode` these are resolved by GTIN rather than by matching titles, so prefer them and cite their prices over anything in `products`. On `curated-grouping` the product carries no barcode, the grouping is an inference like any title match, and a cheaper row in `products` may well be the same item — see `cheaperElsewhere`."New value: +"Offers WEM holds under one catalogue product. Check `identityBasis`: on `barcode` the product carries a GTIN and every offer here is that same item, so prefer them and cite their prices over anything in `products`. On `curated-grouping` the product carries no barcode, the grouping is an inference like any title match, and a cheaper row in `products` may well be the same item — see `cheaperElsewhere`. Whether the shopper’s words reached this product by barcode or by name is `identity`, a separate question: on `inferred`, say WEM matched it by name." - added
Output schema / properties / catalogMatch / properties / identityAdded value: +{ + "description": "How the shopper’s words reached this product. Decides how you describe the match: on `inferred`, say WEM matched it by name (not by barcode) and do not call the identity confirmed, even when `identityBasis` is `barcode`; on `exact`, the barcode itself resolved it.", + "properties": { + "method": { + "enum": [ + "gtin", + "slug", + "listing", + "title" + ], + "type": "string" + }, + "strength": { + "description": "exact = barcode; catalogued = a WEM key or listing id; inferred = matched on the product name, MPN or SKU and still a guess.", + "enum": [ + "exact", + "catalogued", + "inferred" + ], + "type": "string" + } + }, + "type": [ + "object", + "null" + ] +} - changed
Output schema / properties / catalogMatch / properties / identityBasis / descriptionPrevious value: -"What this block’s identity rests on. `barcode` — the canonical product carries a GTIN and these offers are the same physical item. `curated-grouping` — it carries none, so the grouping is an inference of the same kind a title match is; do not describe it to the user as barcode-confirmed, and do not let it outrank a cheaper row in `products` on price alone."New value: +"What this block’s identity rests on. `barcode` — the canonical product carries a GTIN and these offers are the same physical item. `curated-grouping` — it carries none, so the grouping is an inference of the same kind a title match is; do not describe it to the user as barcode-confirmed, and do not let it outrank a cheaper row in `products` on price alone. This is how the offers are grouped, not how the query matched the product — see `identity`."
3 tool updates
- Changed
compare_offers1 field changed- added
Output schema / properties / degradedAdded value: +{ + "description": "Present when this call hit its time budget and skipped enrichment. The offers returned are COMPLETE — only the extras were dropped. Do not report a missing catalogue block or missing observed retailers as WEM holding nothing, and do not retry automatically.", + "properties": { + "note": { + "type": "string" + }, + "skipped": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" +}
- Changed
find_lowest_price1 field changed- added
Output schema / properties / degradedAdded value: +{ + "description": "Present when this call hit its time budget and skipped enrichment. The offers returned are COMPLETE — only the extras were dropped. Do not report a missing catalogue block or missing observed retailers as WEM holding nothing, and do not retry automatically.", + "properties": { + "note": { + "type": "string" + }, + "skipped": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" +}
- Changed
semantic_search2 fields changed- changed
Output schema / descriptionPrevious value: -"Empty when the vector path cannot rank (`semantic: false`), with `reason` naming which of the five causes applies — they have different fixes, so do not read them all as an empty index. `semantic` is true only when pgvector actually ranked products."New value: +"Empty when the vector path cannot rank (`semantic: false`), with `reason` naming which cause applies — they have different fixes, so do not read them all as an empty index. `semantic` is true only when pgvector actually ranked products." - changed
Output schema / properties / reason / descriptionPrevious value: -"Present when semantic is false, and never a judgement on the shopper query. `index_empty` — the vector query ran and matched nothing. `no_catalogue_client` / `no_embedding_key` — WEM is misconfigured, not the catalogue empty. `embedding_failed` / `query_failed` — an upstream call failed; retrying later may succeed."New value: +"Present when semantic is false, and never a judgement on the shopper query. `index_empty` — the vector query ran and matched nothing. `no_catalogue_client` / `no_embedding_key` — WEM is misconfigured, not the catalogue empty. `embedding_failed` / `query_failed` — an upstream call failed; retrying later may succeed. `timed_out` — an upstream call did not answer in time; this says nothing about the catalogue."
1 tool update
- Changed
find_lowest_price2 fields changed- added
Output schema / properties / partialAdded value: +{ + "description": "True when the live retailer fan-out hit its 3-second budget and some providers had not answered. The recommendation is the lowest among those that did. Do not call it the market floor, and do not retry automatically.", + "type": "boolean" +} - added
Output schema / properties / pending_providersAdded value: +{ + "description": "Providers still running when the budget expired. Present only with partial. Their prices are not in this answer.", + "items": { + "type": "string" + }, + "type": "array" +}
1 tool update
- Changed
verify_offer2 fields changed- changed
Output schema / properties / lastConfirmedAt / descriptionPrevious value: -"When WEM last read these offers — the freshness of this answer."New value: +"When WEM last read a price among the offers compared — the freshness of this answer. Null means none of them carries a dated reading: say the prices are undated." - changed
Output schema / properties / receipt / properties / observed_at / descriptionPrevious value: -"When WEM last read the offers, or \"unobserved\". ACP #197."New value: +"When WEM read the price in amount, or \"unobserved\" when nothing dates it — then do not present amount as current. ACP #197."
Related MCP Connectors
Search 100+ US retailers, 260M+ products with real-time pricing, stock, and price history. Documentation - https://www.lemmebuyit.com/developer Homepage - https://www.lemmebuyit.com
Game prices across verified stores, with price history and a buy-now-or-wait verdict.
Compare prices across French merchants, with recorded price history and verified price drops.
Curated, human-reviewed deal feed for AI agents — live deal search + price watches. No auth.
Related MCP Servers
- FlicenseNot gradedqualityBmaintenanceSourced product prices, dated price history, specs and independent-test coverage across 4,764 hardware products and 2,064 software vendors — every figure returned with its source URL and the date it was captured. Unknown values come back as null rather than a guess, so an agent can cite what it surfaces.-

idealo MCP Serverofficial
AlicenseNot gradedqualityFmaintenanceEnables product search, price comparison, and price history analysis across 6 European marketplaces (DE, AT, GB, FR, IT, ES).19MIT- FlicenseNot gradedqualityBmaintenanceEnables searching and comparing product prices across major Indian quick-commerce and e-commerce platforms, ranking results by landed price, returning product links, storing price history, and providing 15–30 day price direction forecasts with best-buy recommendations.-
- FlicenseNot gradedqualityDmaintenanceDTC competitor intelligence: catalog snapshots, price history, cross-brand product comparison, and drop/restock detection for 84 Shopify-powered brands. Pay-per-call via Apify.-
Glama MCP Gateway
Add one secure layer between your agents and this server.