Version 1.2 · Published 28 August 2026

The WEM Verified Offer Standard

AI assistants are starting to answer “what should I buy?” — and to state prices as fact while doing it. Existing standards describe how an offer is expressed and how an agentic transaction is executed; what they do not define is the evidence an independent checker should hold before presenting a retail price as verified. These are the criteria WEM requires of itself, published so that someone who does not trust us can test them.

Scope. This standard governs whether WEM may describe a retail offer as verified. It does not govern product recommendation, merchant ranking, checkout or payment. Schema.org describes how offers are expressed; UCP and ACP define how agentic transactions are executed. This is the evidence layer underneath a stated price.

1. Resolved product identity

The offer is tied to a specific product identity: a global identifier (GTIN/EAN/UPC) where one exists, otherwise brand plus manufacturer model and the variant attributes that distinguish it, otherwise a retailer's own listing id already linked to a catalogue product. Where identity rests on a name match instead, the answer says so and is never presented as exact.

Normative requirement
A resolution made by title similarity alone MUST NOT be reported as an exact identity, and an offer MUST carry the method by which it was identified.

Most wrong price comparisons are not wrong prices; they are the wrong product. A 100ml bottle compared against a 50ml one produces a real number about the wrong thing, and no amount of price accuracy repairs it. Not every product carries a barcode, so the rule is a ladder rather than a gate — what it forbids is presenting the bottom rung as the top one.

WEM implementation: gtin.ts (check-digit validated), canonical-lookup.ts; verify_offer returns identity.method and identity.strength

2. Observed at the retailer's own surface, not submitted through a feed

The price was read by WEM from a surface the retailer serves to shoppers — their product page, or a first-party API that returns the customer-facing transactional offer. A price taken from an affiliate, comparison or promotional feed does not qualify as an observation, whichever transport delivers it.

Normative requirement
A verified price MUST come from an observation of the retailer's customer-facing or transactional surface. A feed MAY identify candidate products and offers, but MUST NOT be the sole evidence for a verified price — and an endpoint that serves syndicated feed data MUST be treated as a feed regardless of being called an API.

A feed is evidence of what a merchant said. An observation is evidence of what a shopper could actually see. Both surfaces belong to the retailer — the difference is not who controls them but what they bind: the page is the one a customer transacts on, while a feed is a copy prepared for redistribution that can drift from it without consequence. Detecting that drift is the whole job, and it cannot be done from the copy alone.

WEM implementation: price-observation.ts — feed:* is never an observation

3. Timestamped, and the age is disclosed

Every observation carries the moment it was made, and anything published says how old it is rather than implying "now".

Normative requirement
Every observation MUST carry the time it was made, and any published price MUST disclose that time or its age.

A price with no time attached is unfalsifiable — it cannot be shown wrong, so it cannot be shown right either. "Checked 4 hours ago" is a weaker claim than "live" and an honest one.

WEM implementation: price_history.recorded_at; verify_offer returns lastConfirmedAt

4. Labelled provenance, on every single row

Each observation records how it was made, and the label travels with it: retailer API, browser extension reading the page, or a human who opened it.

Normative requirement
Provenance MUST be recorded per observation at the moment of collection, not asserted per dataset.

Provenance is a property of the price, not of the dataset. Once observations of different kinds are pooled without a row-level label, no later filter can reconstruct how each price was obtained — so the label is written when the row is, or the row is not admissible.

WEM implementation: price_history.source — api:, extension, operator

5. Availability stated only where it was checked

Availability has three states, not two: reported available, reported unavailable, and not reported. The third is recorded as unknown and never rendered as "in stock".

Normative requirement
Availability MUST NOT be inferred where the source did not report it. Unknown MUST NOT be rendered, ranked, or published as available.

A price for something nobody can buy is not a cheaper option. Defaulting unknown to available is the single easiest way to make a comparison look better than reality — and it is usually done by a database default rather than a decision, which is why the rule forbids the default rather than trusting the intention.

WEM implementation: observedInStock(); canonical_offers.in_stock is nullable and NULL means not reported

6. Silence when the evidence is missing

Where an offer cannot meet these rules, it is excluded from verified results. Nothing is estimated, inferred, or filled in to complete a comparison.

Normative requirement
A missing value MUST NOT be estimated or substituted to complete a comparison. Where evidence is absent the answer MUST be an explicit no-verification result, not a plausible one.

The pressure in comparison is always to show something. A gap teaches a shopper that the absence means something; a plausible guess teaches them nothing and costs them the ability to trust the rest. An offer WEM cannot verify may still be shown as a discovery result — it is verified status it cannot have, and the two are kept apart.

WEM implementation: isPublishableSource() gates every published aggregate and press RPC

7. The answer does not know what it earns

Ranking, selection and verification are computed without reference to commercial terms. Funding is disclosed; it never reaches the ordering.

Normative requirement
No commission, revenue-share or commercial-priority value MUST be available to the code path that verifies an offer or orders results.

Verification is only worth something if the verifier is not paid for the verdict. WEM is funded by affiliate commission and does not pretend that conflict is absent; it is a data-isolation property instead of a promise — the commercial value exists, and the ranking path cannot read it.

WEM implementation: find_lowest_price sorts on price; no commission field reaches ranking

8. Lawful to retain and to republish

An observation is only published where the source's terms permit retention and republication. Where they do not, the data is refused at the writer, not filtered at the reader.

Normative requirement
Data whose terms restrict the retention, comparison or republication a verified result depends on MUST NOT enter the verification corpus, and MUST be refused at collection rather than filtered at publication.

A verification corpus that cannot be shown is not evidence. Sources whose licences cap retention or bar comparison use are excluded before collection, because a clean provenance story does not create a retention right. Which sources those are is an implementation matter and changes as terms do.

WEM implementation: named source exclusions applied in the publishing predicate and both press RPCs

The distinction that does most of the work

Criterion 2 separates two things the word “price” hides. An advertised price is supplied for distribution — through an affiliate, comparison or promotional feed. An observed price is captured by the verifier from the surface the retailer serves to shoppers, whether or not any commercial relationship exists.

A feed is evidence of what a merchant said. An observation is evidence of what a shopper could actually see.

Both surfaces belong to the retailer, so the distinction is not who controls them. It is what they bind: the page is the one a customer transacts on, while a feed is a copy prepared for redistribution that can drift from it without consequence. A feed cannot verify its own price — detecting that drift needs a separate observation path, and that remains true no matter how large the feed is.

Verification is not a price guarantee

A verified offer states what WEM observed and when. The retailer is authoritative at checkout: they set the price, hold the stock, and may change either between our reading and your arrival. WEM never takes payment and guarantees no price.

How to check this without trusting us

Every claim above is a behaviour, so it can be tested from outside. WEM’s MCP server and /api/verify are public and need no key. Each of these takes about a minute.

  • Ask for a price WEM cannot evidence

    Call verify_offer (or POST /api/verify) for a product WEM does not hold.

    Criteria 1 and 6: the answer is `unknown_product` with no price, never an estimate or a nearest guess.

  • Check a price that has moved

    Claim a price that differs from the retailer’s current one.

    Criterion 3: the verdict is `price_moved` and carries `lastConfirmedAt`, so the age of WEM’s reading is visible rather than implied.

  • Look for stock WEM never checked

    Read `inStock` on any offer from a provider that does not report availability.

    Criterion 5: the value is `null`, not `true`.

  • Resolve a product by name rather than barcode

    Pass `title` instead of `gtin` to verify_offer.

    Criterion 1: `identity.strength` comes back `inferred` and the summary says the match was made on the product name.

  • Diff the live answers against the published examples

    Fetch /standard/verified-offer/examples.json and compare its shapes with what the API returns for your own calls.

    Every criterion at once. The examples are generated by the function that answers the live API, so a difference between them and production is a defect on our side, and you can see it without our source.

Source-file references beside each criterion say where the rule lives in WEM’s codebase. That repository is private, so treat those as pointers, not as proof — the checks above are the proof.

What WEM does not claim

  • Not every price on the internet. WEM observes a bounded set of retailers and says nothing about the rest.
  • Not a live quote. An observation has an age; the retailer sets the price at checkout, and WEM never takes payment.
  • Not certification of anyone else. The standard describes what WEM will publish. No third party is audited or endorsed by it today.

Using it

The standard is free to read, cite and apply. If you build commerce data and want to state that you meet it, do — and say which criteria you meet, because the ones a dataset fails are usually the informative ones.

Conformance. An implementation conforms to version 1.2 only if all eight normative requirements are satisfied for every offer it describes as verified. Partial adoption is welcome and useful, but it is not conformance, and should be stated as the specific criteria met rather than as compliance with the standard.

Machine-readable: schema.json defines the verified-offer object, and examples.json carries a worked case for every verdict, including the two that refuse to confirm. The examples are generated from the same function that answers verify_offer in production, so they cannot drift from what the API actually returns.

Agents can call the criteria rather than read them: WEM’s MCP server exposes verify_offer, which answers whether a specific price is supported by observation. It never invents or infers a price; it returns an explicit non-confirming verdict instead, and the three are not the same claim. unknown_product and not_at_retailer mean the claim could not be checked — unchecked, never false. price_moved is stronger: the product and retailer resolved, and WEM’s own reading differs from the claim.

Cite it as: The WEM Verified Offer Standard, version 1.2, wem3.ai/standard/verified-offer.

Change control

Criteria are versioned. Clarifications that do not change what qualifies are published as minor versions; any change that would let data qualify which previously did not requires a new major version, and the superseded edition stays citable. The URL does not move.

1.228 August 2026
Machine-readable conformance, and a tightened criterion 2. Published schema.json and examples.json, both generated from the code that answers the live API rather than written by hand. Added an explicit definition of full conformance — previously the page invited implementers to state which criteria they met without defining what meeting the standard was. Criterion 2 now says an endpoint serving syndicated feed data is a feed whatever it is called, closing the relabelling gap. Corrected the description of non-confirming verdicts: price_moved is a finding, not an absence of evidence, and grouping it with unknown_product understated it. This is a minor version because every change narrows what qualifies or clarifies without moving the bar; nothing that previously failed now passes.
1.128 August 2026
Clarifications following technical review; no criterion was weakened. Narrowed the opening claim to acknowledge schema.org, UCP and ACP; added the scope statement and RFC 2119 wording; corrected criterion 2 to distinguish a retailer’s authoritative surface from a feed submitted for redistribution, and removed an incorrect generalisation that comparison feeds are paid per click; corrected criterion 4’s claim about pooled data; stated criterion 5’s three states explicitly; removed named providers from criterion 8; relabelled implementation pointers, which are not externally auditable in a private repository, and added the public checks above.
1.028 August 2026
Initial publication.

Related: the pre-registered Black Friday methodology applies this standard to a specific study, committed before the data was collected. WEM is funded by disclosed affiliate commission — how that works.