The bridge between a canonical product and a seller's own world. One Listing per (product, seller) pair, carrying that seller's identifier, URL and — critically — how confident we are that the mapping is right.
| Field | Type | Notes |
|---|---|---|
| listing_id ·always | string | Stable. |
| product_id ·always | string | What it resolved to. |
| seller ·always | string | Seller id, e.g. bestbuy or allbirds.com. |
| seller_sku ·always | string | The seller's own identifier. |
| url | string | null | Canonical product link at that seller. |
| match.method | enum | gtin_exact | mpn_exact | title_fuzzy | manual. |
| match.confidence | float | 0–1. Below 0.7 the listing is flagged for review rather than silently trusted. |
| first_seen / last_seen | timestamp | How long this seller has carried it. |
| active | bool | False once the seller stops carrying it. Rows are never deleted. |
{
"listing_id": "lst_2c81",
"product_id": "prd_8Fk2xQ",
"seller": "bestbuy",
"seller_sku": "6505727",
"url": "https://www.bestbuy.com/product/…",
"match": { "method": "gtin_exact", "confidence": 1.0 },
"first_seen": "2026-06-09T13:21:15Z",
"last_seen": "2026-09-08T14:02:11Z",
"active": true
}A seller dropping a product is information. The row goes inactive and its history stays queryable, because assortment change is one of the more useful signals in the dataset.
A mapping correct in March can be wrong in September when a seller relists under a new title or bundles the item. That produces a `match.degraded` event rather than a silent, ongoing comparison of two different products.