Docs / Modelo de datosData modelMarkdown

Modelo de datos

Tres objetos explican casi todo:

  • Producto: el artículo, igual en todas las tiendas (prd_). Tiene marca, categoría, tamaño y códigos de barras (GTIN).
  • Oferta: ese producto en una tienda (ofr_), con su URL y su título original.
  • Observación: lo que vimos en una oferta en un momento: precio, condiciones, stock y de dónde salió. Las observaciones no se modifican; el historial es la serie de observaciones.

Precio: qué significa cada campo#

price es lo que paga cualquier persona sin condiciones: el precio de oferta si existe, si no el de lista. Lo condicionado va aparte, para que nadie lo presente como "el precio".

CampoQué es
list_pricePrecio normal publicado
sale_pricePrecio rebajado sin condiciones, o null
priceEl menor de los dos: lo que paga cualquiera
conditional_prices[]Precios que exigen algo distinto de la cantidad: medio de pago, nivel de club, app o cupón
card_price, card_labelAtajo: el menor precio con tarjeta o membresía (por ejemplo "Tarjeta Cencosud")
promotions[]Exigen cantidad o combinación: "2 x $2.590", la segunda unidad, porcentaje
unit_pricePrecio por unidad base (kg, l, unidad, m o m2), para comparar tamaños
installmentsCuotas sin interés de la oferta
availabilityStock: in_stock, out_of_stock, limited o unknown

Procedencia#

Cada precio dice de dónde salió, para que cualquiera lo pueda comprobar:

CampoQué es
urlLa ficha del producto en la tienda
observed_atFecha y hora de la captura, en UTC
observed_local_dateFecha de la captura en la zona de la tienda
capture_methodpublic_page (la página pública), public_api (un endpoint abierto del sitio), retailer_feed (entregado por la tienda) u open_data (un dataset público)
meta.attribution.textUna línea lista para citar: marca, tienda, hora e id

Mismo producto entre tiendas#

Cada oferta trae match: cómo se unió al producto y con qué confianza.

CampoQué es
match.methodCómo se unió: por GTIN, por reglas o por un modelo
match.confidenceEntre 0 y 1
match.kindidentical (el mismo artículo), pack (N unidades del producto, ver pack_ratio) o equivalent (sustituto de otra marca)
match.pack_ratioCuántas unidades trae el pack

Por defecto los precios y las comparaciones agrupan solo ofertas identical con confianza de 0,85 o más. min_confidence y match_kinds (por ejemplo identical,pack) amplían el grupo, y meta.warnings avisa cuando quedaron ofertas fuera. En un pack, compara por unit_price.

Calidad#

Los precios se entregan tal como los publica la tienda, nunca corregidos. Si una validación ve algo raro, el precio llega con quality_status: "warning" y la razón en quality_flags[]: discount_over_85 (descuento sobre 85 % del precio normal) o round_price_low (precio redondo de $1.000 o menos). Si una observación se enmendó después de capturada, corrected es true y el original se guarda.

Moneda, impuestos e idioma#

  • Montos en la moneda de la tienda; CLP no tiene decimales. currency=USD agrega converted con la tasa, su fecha y su fuente.
  • tax_included dice si el precio publicado incluye impuestos (en Chile, sí). tax_rate y price_ex_tax se derivan de la regla del país (tax_rule_id), o vienen en null si no hay regla.
  • Nombres y categorías en español o inglés según lang; names trae todos los idiomas y title_original, el título de la tienda sin traducir.

Taxonomía#

Las categorías son un árbol con ids legibles (food.dairy.milk): filtrar por food.dairy incluye sus subcategorías. El árbol completo está en GET /v1/categories.

Campos#

Precio en una tienda (RetailerPrice)#

CampoTipoDescripción
currency requeridostring
price requeridonumber
list_price requeridonumber
sale_pricenumber | null
card_pricenumber | nullConvenience: the lowest price in conditional_prices that requires a payment method or membership.
card_labelstring | null
conditional_pricesConditionalPrice[]Every price that requires a condition other than quantity (payment method, loyalty tier, app, coupon), as published.
conditional_prices[].kind requeridostringValores / values: payment_method, membership, app_only, coupon, other.
conditional_prices[].label requeridostringAs shown by the retailer.
conditional_prices[].price requeridonumber
conditional_prices[].payment_methodstring | null
conditional_prices[].membership_tierstring | null
conditional_prices[].installments_countinteger | null
conditional_prices[].interest_freeboolean | null
unit_priceobject | null
unit_price.amount requeridonumber
unit_price.per requeridostringValores / values: kg, l, unit, m, m2.
promotionsPromotion[]
promotions[].type requeridostringValores / values: multi_buy, nth_unit, percent_off, amount_off, bundle, gift, other.
promotions[].label requeridostringAs shown by the retailer, e.g. "2 x $2.990".
promotions[].min_quantityinteger | null
promotions[].effective_unit_pricenumber | nullPrice per item when the promotion applies.
promotions[].requires_cardstring | nullPayment method required, if any.
promotions[].valid_untilstring (date) | null
availability requeridostringValores / values: in_stock, out_of_stock, limited, unknown.
tax_includedbooleanAs shown by the retailer (observed).
tax_ratenumber | nullDerived. Main VAT rate for this country and category, null when not known.
price_ex_taxnumber | nullDerived from price and tax_rate. Null when tax_rate is null.
tax_rule_idstring | nullVersioned rule used to derive tax_rate.
other_taxes_includedboolean | nullTrue when other taxes remain in price_ex_tax (e.g. Chile IABA on sweetened drinks).
installmentsobject
observed_at requeridostring (date-time)
observed_local_datestring (date)Capture date in the retailer time zone. Daily series use this date.
capture_method requeridostringHow the price was obtained, part of the provenance with url and observed_at. public_page: read from the retailer's public web page (HTML, JSON-LD or the page payload). public_api: an open, unauthenticated JSON endpoint of the retailer's own site. retailer_feed: delivered by the retailer under an agreement. open_data: a public dataset published by a government or third party. Valores / values: public_page, public_api, retailer_feed, open_data.
quality_statusstringwarning when a validation flagged the observation (price jump, zero, unusual unit). Quarantined observations are never served. Valores / values: ok, warning.
quality_flagsstring[]Why the price was flagged. The price is delivered as published, never corrected. discount_over_85: more than 85% off the list price. round_price_low: a round price of CLP 1,000 or less. Both often mean a placeholder price or a store error.
correctedbooleanTrue when the observation was amended after capture (the original is kept).
convertedConverted
converted.currency requeridostring
converted.price requeridonumber
converted.list_pricenumber | null
converted.card_pricenumber | null
converted.unit_pricenumber | null
converted.fx_rate requeridonumberUnits of target currency per unit of source currency.
converted.fx_date requeridostring (date)Publication date of the rate used (last published on or before the observation date).
converted.fx_sourcestring
converted.fx_methodstringValores / values: direct, cross.
retailer requeridoRetailerRef
retailer.id requeridostring
retailer.name requeridostring
offer_id requeridostring
store_idstring | nullNull when the price is national/online.
url requeridostring (uri)
title_original requeridostring
sellerSellerWho sells the offer. On marketplaces it is a third party; name is null when the seller is a natural person (no personal data).
seller.id requeridostring
seller.name requeridostring | null
seller.is_retailer_itself requeridoboolean
match requeridoMatchHow the offer was linked to the canonical product.
match.method requeridostringsingleton: the offer matched nothing else and is its own product. Valores / values: gtin, rules, model, manual, singleton.
match.confidence requeridonumber
match.kind requeridostringidentical: the same item. pack: the offer is N units of the product (pack_ratio), comparable by unit price. equivalent: a declared substitute of another brand or lab, not the same item. Valores / values: identical, pack, equivalent.
match.pack_rationumber | nullUnits of the product in the offer, for kind pack.

Producto (Product)#

CampoTipoDescripción
id requeridostring
name requeridostring
brand requeridoBrandRef
brand.id requeridostring
brand.name requeridostring
category requeridoCategoryRef
category.id requeridostring
category.label requeridostring
category.pathstring[]
sizeobject
gtinstring[]
image_urlstring | null
price_summary requeridoPriceSummary
price_summary.currency requeridostring
price_summary.min requeridonumber | null
price_summary.max requeridonumber | null
price_summary.mediannumber | null
price_summary.offers_count requeridointeger
price_summary.retailers_count requeridointeger
price_summary.bestobject | null
price_summary.observed_atstring (date-time) | null
price_summary.convertedobject
scorenumberRelevance score, search only.
namesobjectName in every available language.
names_metaobjectProvenance of each name, keyed by language.
private_labelbooleanStore brand of one retailer.
relationsobject[]Links to other canonical products.
relations[].kind requeridostringValores / values: pack_of, size_of, variant_of, equivalent, replaced_by.
relations[].product_id requeridostring
relations[].quantity_ratio requeridonumber | nullFor pack_of and size_of, how many units of product_id this product contains.
identifiersobject
identifiers.gtinstring[]
identifiers.mpnstring | null
attributesobject
countriesstring[]
first_seenstring (date-time)

Precio condicional (ConditionalPrice)#

CampoTipoDescripción
kind requeridostringValores / values: payment_method, membership, app_only, coupon, other.
label requeridostringAs shown by the retailer.
price requeridonumber
payment_methodstring | null
membership_tierstring | null
installments_countinteger | null
interest_freeboolean | null

Promoción (Promotion)#

CampoTipoDescripción
type requeridostringValores / values: multi_buy, nth_unit, percent_off, amount_off, bundle, gift, other.
label requeridostringAs shown by the retailer, e.g. "2 x $2.990".
min_quantityinteger | null
effective_unit_pricenumber | nullPrice per item when the promotion applies.
requires_cardstring | nullPayment method required, if any.
valid_untilstring (date) | null

Atribución (Attribution)#

CampoTipoDescripción
text requeridostring
source requeridostringBrand name.
as_of requeridostring (date-time)
resource_id requeridostring | nullProduct or offer the response is about
url requeridostring (uri) | nullPublic page for the product
capture_methodstring | nullSet when the response is about one offer. Valores / values: public_page, public_api, retailer_feed, open_data.
source_urlstring (uri) | nullRetailer URL of the offer, when the response is about one offer.

Conversión (Converted)#

CampoTipoDescripción
currency requeridostring
price requeridonumber
list_pricenumber | null
card_pricenumber | null
unit_pricenumber | null
fx_rate requeridonumberUnits of target currency per unit of source currency.
fx_date requeridostring (date)Publication date of the rate used (last published on or before the observation date).
fx_sourcestring
fx_methodstringValores / values: direct, cross.

Punto del historial (HistoryPoint)#

CampoTipoDescripción
t requeridostringDate (day, week, month start) or timestamp (raw).
price requeridonumber
list_price requeridonumber
sale_pricenumber | null
card_pricenumber | null
availability requeridostringValores / values: in_stock, out_of_stock, limited, unknown.
convertedobjectPresent when currency is set. Converted with the rate of the point date (or fx_date).
converted.pricenumber
converted.list_pricenumber
converted.fx_ratenumber
converted.fx_datestring (date)

Data model

Three objects explain almost everything:

  • Product: the item, the same at every store (prd_). It has a brand, a category, a size and barcodes (GTIN).
  • Offer: that product at one store (ofr_), with its URL and original title.
  • Observation: what we saw on an offer at one moment: price, conditions, stock and where it came from. Observations are never modified; history is the series of observations.

Price: what each field means#

price is what anyone pays with no conditions: the sale price if there is one, otherwise the list price. Conditional prices come separately, so nobody presents them as "the price".

FieldWhat it is
list_priceRegular published price
sale_priceUnconditional sale price, or null
priceThe lower of the two: what anyone pays
conditional_prices[]Prices that require something other than quantity: payment method, loyalty tier, app or coupon
card_price, card_labelShortcut: the lowest price with a card or membership (for example "Tarjeta Cencosud")
promotions[]Require a quantity or combination: "2 x CLP 2,590", second unit, percentage
unit_pricePrice per base unit (kg, l, unit, m or m2), to compare sizes
installmentsInterest-free installments on the offer
availabilityStock: in_stock, out_of_stock, limited or unknown

Provenance#

Every price says where it came from, so anyone can check it:

FieldWhat it is
urlThe product page at the store
observed_atCapture date and time, UTC
observed_local_dateCapture date in the store's time zone
capture_methodpublic_page (the public page), public_api (an open endpoint on the site), retailer_feed (provided by the store) or open_data (a public dataset)
meta.attribution.textA line ready to quote: brand, store, time and id

Same product across stores#

Every offer carries match: how it was joined to the product and with what confidence.

FieldWhat it is
match.methodHow it was joined: by GTIN, by rules or by a model
match.confidenceBetween 0 and 1
match.kindidentical (the same item), pack (N units of the product, see pack_ratio) or equivalent (a substitute from another brand)
match.pack_ratioHow many units the pack holds

By default prices and comparisons group only identical offers with confidence of 0.85 or more. min_confidence and match_kinds (for example identical,pack) widen the group, and meta.warnings notes when offers were left out. For a pack, compare by unit_price.

Quality#

Prices are delivered as the store publishes them, never corrected. If a validation sees something odd, the price comes with quality_status: "warning" and the reason in quality_flags[]: discount_over_85 (a discount above 85% of the regular price) or round_price_low (a round price of CLP 1,000 or less). If an observation was amended after capture, corrected is true and the original is kept.

Currency, taxes and language#

  • Amounts in the store's currency; CLP has no decimals. currency=USD adds converted with the rate, its date and its source.
  • tax_included says whether the published price includes taxes (in Chile, it does). tax_rate and price_ex_tax are derived from the country rule (tax_rule_id), or come as null if there is no rule.
  • Names and categories in Spanish or English depending on lang; names carries every language and title_original the store's untranslated title.

Taxonomy#

Categories are a tree with readable ids (food.dairy.milk): filtering by food.dairy includes its subcategories. The full tree is at GET /v1/categories.

Fields#

Price at a store (RetailerPrice)#

FieldTypeDescription
currency requiredstring
price requirednumber
list_price requirednumber
sale_pricenumber | null
card_pricenumber | nullConvenience: the lowest price in conditional_prices that requires a payment method or membership.
card_labelstring | null
conditional_pricesConditionalPrice[]Every price that requires a condition other than quantity (payment method, loyalty tier, app, coupon), as published.
conditional_prices[].kind requiredstringValores / values: payment_method, membership, app_only, coupon, other.
conditional_prices[].label requiredstringAs shown by the retailer.
conditional_prices[].price requirednumber
conditional_prices[].payment_methodstring | null
conditional_prices[].membership_tierstring | null
conditional_prices[].installments_countinteger | null
conditional_prices[].interest_freeboolean | null
unit_priceobject | null
unit_price.amount requirednumber
unit_price.per requiredstringValores / values: kg, l, unit, m, m2.
promotionsPromotion[]
promotions[].type requiredstringValores / values: multi_buy, nth_unit, percent_off, amount_off, bundle, gift, other.
promotions[].label requiredstringAs shown by the retailer, e.g. "2 x $2.990".
promotions[].min_quantityinteger | null
promotions[].effective_unit_pricenumber | nullPrice per item when the promotion applies.
promotions[].requires_cardstring | nullPayment method required, if any.
promotions[].valid_untilstring (date) | null
availability requiredstringValores / values: in_stock, out_of_stock, limited, unknown.
tax_includedbooleanAs shown by the retailer (observed).
tax_ratenumber | nullDerived. Main VAT rate for this country and category, null when not known.
price_ex_taxnumber | nullDerived from price and tax_rate. Null when tax_rate is null.
tax_rule_idstring | nullVersioned rule used to derive tax_rate.
other_taxes_includedboolean | nullTrue when other taxes remain in price_ex_tax (e.g. Chile IABA on sweetened drinks).
installmentsobject
observed_at requiredstring (date-time)
observed_local_datestring (date)Capture date in the retailer time zone. Daily series use this date.
capture_method requiredstringHow the price was obtained, part of the provenance with url and observed_at. public_page: read from the retailer's public web page (HTML, JSON-LD or the page payload). public_api: an open, unauthenticated JSON endpoint of the retailer's own site. retailer_feed: delivered by the retailer under an agreement. open_data: a public dataset published by a government or third party. Valores / values: public_page, public_api, retailer_feed, open_data.
quality_statusstringwarning when a validation flagged the observation (price jump, zero, unusual unit). Quarantined observations are never served. Valores / values: ok, warning.
quality_flagsstring[]Why the price was flagged. The price is delivered as published, never corrected. discount_over_85: more than 85% off the list price. round_price_low: a round price of CLP 1,000 or less. Both often mean a placeholder price or a store error.
correctedbooleanTrue when the observation was amended after capture (the original is kept).
convertedConverted
converted.currency requiredstring
converted.price requirednumber
converted.list_pricenumber | null
converted.card_pricenumber | null
converted.unit_pricenumber | null
converted.fx_rate requirednumberUnits of target currency per unit of source currency.
converted.fx_date requiredstring (date)Publication date of the rate used (last published on or before the observation date).
converted.fx_sourcestring
converted.fx_methodstringValores / values: direct, cross.
retailer requiredRetailerRef
retailer.id requiredstring
retailer.name requiredstring
offer_id requiredstring
store_idstring | nullNull when the price is national/online.
url requiredstring (uri)
title_original requiredstring
sellerSellerWho sells the offer. On marketplaces it is a third party; name is null when the seller is a natural person (no personal data).
seller.id requiredstring
seller.name requiredstring | null
seller.is_retailer_itself requiredboolean
match requiredMatchHow the offer was linked to the canonical product.
match.method requiredstringsingleton: the offer matched nothing else and is its own product. Valores / values: gtin, rules, model, manual, singleton.
match.confidence requirednumber
match.kind requiredstringidentical: the same item. pack: the offer is N units of the product (pack_ratio), comparable by unit price. equivalent: a declared substitute of another brand or lab, not the same item. Valores / values: identical, pack, equivalent.
match.pack_rationumber | nullUnits of the product in the offer, for kind pack.

Product (Product)#

FieldTypeDescription
id requiredstring
name requiredstring
brand requiredBrandRef
brand.id requiredstring
brand.name requiredstring
category requiredCategoryRef
category.id requiredstring
category.label requiredstring
category.pathstring[]
sizeobject
gtinstring[]
image_urlstring | null
price_summary requiredPriceSummary
price_summary.currency requiredstring
price_summary.min requirednumber | null
price_summary.max requirednumber | null
price_summary.mediannumber | null
price_summary.offers_count requiredinteger
price_summary.retailers_count requiredinteger
price_summary.bestobject | null
price_summary.observed_atstring (date-time) | null
price_summary.convertedobject
scorenumberRelevance score, search only.
namesobjectName in every available language.
names_metaobjectProvenance of each name, keyed by language.
private_labelbooleanStore brand of one retailer.
relationsobject[]Links to other canonical products.
relations[].kind requiredstringValores / values: pack_of, size_of, variant_of, equivalent, replaced_by.
relations[].product_id requiredstring
relations[].quantity_ratio requirednumber | nullFor pack_of and size_of, how many units of product_id this product contains.
identifiersobject
identifiers.gtinstring[]
identifiers.mpnstring | null
attributesobject
countriesstring[]
first_seenstring (date-time)

Conditional price (ConditionalPrice)#

FieldTypeDescription
kind requiredstringValores / values: payment_method, membership, app_only, coupon, other.
label requiredstringAs shown by the retailer.
price requirednumber
payment_methodstring | null
membership_tierstring | null
installments_countinteger | null
interest_freeboolean | null

Promotion (Promotion)#

FieldTypeDescription
type requiredstringValores / values: multi_buy, nth_unit, percent_off, amount_off, bundle, gift, other.
label requiredstringAs shown by the retailer, e.g. "2 x $2.990".
min_quantityinteger | null
effective_unit_pricenumber | nullPrice per item when the promotion applies.
requires_cardstring | nullPayment method required, if any.
valid_untilstring (date) | null

Attribution (Attribution)#

FieldTypeDescription
text requiredstring
source requiredstringBrand name.
as_of requiredstring (date-time)
resource_id requiredstring | nullProduct or offer the response is about
url requiredstring (uri) | nullPublic page for the product
capture_methodstring | nullSet when the response is about one offer. Valores / values: public_page, public_api, retailer_feed, open_data.
source_urlstring (uri) | nullRetailer URL of the offer, when the response is about one offer.

Conversion (Converted)#

FieldTypeDescription
currency requiredstring
price requirednumber
list_pricenumber | null
card_pricenumber | null
unit_pricenumber | null
fx_rate requirednumberUnits of target currency per unit of source currency.
fx_date requiredstring (date)Publication date of the rate used (last published on or before the observation date).
fx_sourcestring
fx_methodstringValores / values: direct, cross.

History point (HistoryPoint)#

FieldTypeDescription
t requiredstringDate (day, week, month start) or timestamp (raw).
price requirednumber
list_price requirednumber
sale_pricenumber | null
card_pricenumber | null
availability requiredstringValores / values: in_stock, out_of_stock, limited, unknown.
convertedobjectPresent when currency is set. Converted with the rate of the point date (or fx_date).
converted.pricenumber
converted.list_pricenumber
converted.fx_ratenumber
converted.fx_datestring (date)