Price record
A public record of what every Storeware shop offered things at, so an agent can check a was price before repeating it.
A "was" price is a claim. An agent that repeats a false one to a person has been used to mislead them, and until now it had no way to check. Every Storeware shop keeps a public, tamper-evident record of the prices it listed.
What to do with it
When a UCP variant shows a list_price above its price, it carries a link:
{
"price": { "amount": 7000, "currency": "GBP" },
"list_price": { "amount": 10000, "currency": "GBP" },
"ai.storeware.shopping.price_record": {
"url": "https://api.storeware.ai/api/price-record/variants/<variant id>"
}
}Fetch it. No key is needed. Each currency gives you facts:
| Field | Meaning |
|---|---|
recordedSince | The first moment the record shows this on sale |
reducedSince | When the current price began, if the price before it was higher |
lowestBefore | The lowest price in the 30 days before the reduction, the days listed in that time, and whether that was the whole window |
daysAtWasPrice | Days on sale at the was price |
Facts, never a score. If daysAtWasPrice is 0, the record has never seen this on sale at the was price. That may mean the sale is older than the record, so read recordedSince before you decide what to tell anybody.
A 404 means the shop keeps its record to itself. It does not mean the price is false.
What it proves, and what it does not
It shows the price and was price a shop listed, and roughly when.
- A date is compared with the first outside stamp covering it. More than three days before that stamp it is reported as unconfirmed, and so is an old entry with no stamp. This rests on the stamp being real, so check its signature if the date matters.
- Listed is not in stock. A sold-out thing still counts as listed.
- It does not prove that anybody paid that price.
- It does not cover discount codes, basket offers or agreed trade prices.
- It cannot show that a later entry was not left out.
- A product deleted and made again starts a new record, and so does one imported from another platform.
- A shop can switch off showing its record. While it is off, the record answers 404, and nothing shows it was ever off.
- Deleting a shop removes its figures for good. Only the hashes stay.
Prices already on a shop when the record began are marked carried_over and dated the day they were logged. A price from before a thing was listed is never shown, and neither is any price of a draft.
Check it yourself
You need no Storeware code. A record is checked in five steps, and the verifier does all of them in one file:
- The figures. For each entry that shows them,
sha256(salt || canonical values)equals thecommitin its header. - The chain. Each header names the leaf hash of the one before, starting from null, so an entry cannot be taken out of the middle.
- The tree. The newest leaf's RFC 6962 inclusion proof reaches the root in the head.
- The head. The head is a C2SP signed note under the log's Ed25519 key, which never changes:
{ "kty": "OKP", "crv": "Ed25519", "x": "vP_5IEr3wODGjqwdMQl7D-7qIpZoFvIl044eN-WmST4" }- The dates. Each witness proves an entry was in a stamped head. An entry dated after that stamp is refused. One dated more than three days before it is unconfirmed, and the verifier exits 3.
What a rewrite would take
A signature only proves Storeware said something, so the dates rest on other people. Each day the newest head goes to two independent RFC 3161 timestamp authorities, who hear only a hash. The newest stamped head is stamped on the head route:
curl -s https://api.storeware.ai/api/price-record/head | jq -j .stamped.checkpoint > head.txt
curl -s https://api.storeware.ai/api/price-record/head | jq -r '.stamped.anchors[0].token' | base64 -d > stamp.tsr
openssl ts -reply -in stamp.tsr -text
openssl dgst -sha256 head.txtCompare the message data in the reply with the digest, or run openssl ts -verify with the authority's certificates.
A stamp dates a head. It does not stop Storeware building a different tree and having that stamped today. What a rewrite cannot do is match a head somebody already kept, so the record is tamper-evident to anybody who keeps one. Keep a head, and later ask for the proof between it and a newer one:
GET https://api.storeware.ai/api/price-record/consistency?from=<old size>&to=<new size>| Route | Answers |
|---|---|
GET /api/price-record/head | The newest head, or ?size= for an older one |
GET /api/price-record/consistency?from=&to= | Proof the older tree is the start of the newer |
GET /api/price-record/variants/{id} | One variant's record, facts and proof |
GET /api/price-record/leaves?from= | Leaf hashes from an index, a page at a time |