Semantic model
This page defines the stable meaning of Extralt data. It is not a description of the physical ClickHouse layout.
Use the OpenAPI reference for exact request and response schemas. Use this page when you need to understand what one record represents, how records relate, and which facts can be compared safely.
Two data layers
Extralt exposes two related layers:
- Queryable records preserve page observations and processing lineage.
The constrained SQL surface currently supports
captures,items, andchanges. - Extend entities connect observations into Product, Variant, Listing, Offer, Review, and Store relationships. They are currently exposed through purpose-built Explore views and APIs, not as arbitrary public SQL tables.
Do not assume that a ClickHouse table exists, or that it can be queried, because an entity appears in this model. See the access-surface matrix for the current contract.
Queryable records
The types in this section are the types visible to the constrained SQL query surface. API payloads can represent the same values differently; OpenAPI is the authority for JSON payloads.
Only the fields listed below are part of the documented query contract. Select
columns explicitly rather than depending on SELECT *: service-scoping,
search-index, or reserved columns can be present and can change without becoming
customer metrics.
captures
Grain: one successfully extracted or imported page record.
Identity: id.
Lineage: Run or Import -> Capture.
Use it for: source evidence, extraction output, exports, and Enrich input.
Identity, source, and time
| Field | SQL type | Meaning |
|---|---|---|
id | UInt64 | Capture identifier and query cursor. |
run_id | String | Extract Run id, or batch id for an imported Capture. |
is_import | Bool | Whether the Capture originated from an Import. |
robot_id | String | Robot that extracted the page. Empty for imports. |
robot_name | String | Robot name copied at observation time. |
run_name | String | Run or import-batch name. |
run_started_at | DateTime64(3) | Observation time inherited from the Run or import batch. |
host | String | Host of the source URL. |
country | String | Country selected for the extraction context. |
language | String | Detected source-page language when available. |
url | String | Source URL retained as evidence. |
Source product fields
| Field | SQL type | Meaning |
|---|---|---|
product_id | String | Source product-family key when the site exposes one. This is not an Extend Product id. |
handle | String | Source handle or grouping key. |
title, subtitle | String | Source text in its original language. |
brand | String | Source brand value. |
breadcrumbs | String | Serialized source breadcrumbs. |
description | String | Source description. |
color | String | Page-level source color value. |
publication_date | String | Source value before Enrich parses it. |
gender, age_group | String | Source audience values. |
ratings_average | Float64 | Source rating average; interpret with ratings_scale. |
ratings_count | UInt32 | Source rating or review count. |
ratings_scale | UInt8 | Source scale, such as 5 or 10. |
Commerce summary and collections
| Field | SQL type | Meaning |
|---|---|---|
min_price, max_price | Decimal32(2) | Price range observed within this Capture. |
currency | String | Currency of the page-level range. |
available | Bool | Page-level availability summary. |
sku_count | UInt16 | Number of extracted source SKUs. |
image_url | String | Representative source image. |
categories, tags | Array(String) | Source categories and tags. |
videos | Array(String) | Source video URLs. |
properties_list | Array(String) | Source properties that are not key-value pairs. |
recommended_products | Array(String) | Source references to recommended products. |
images | JSON-encoded String | Source image records. |
options | JSON-encoded String | Source option axes and values. |
skus | JSON-encoded String | Source SKUs, identifiers, media, prices, sellers, and availability. |
properties_dict | JSON-encoded String | Source key-value properties. |
physical_measurements | JSON-encoded String | Source measurements. |
JSON paths vary with the source evidence. Inspect representative values before depending on a nested path.
items
Grain: one successfully enriched Capture.
Identity: id.
Lineage: Capture -> Enrichment -> Item.
Use it for: normalized, page-grain product data and Extend input.
| Field | SQL type | Meaning |
|---|---|---|
id | UInt64 | Item identifier and query cursor. |
capture_id | UInt64 | Source Capture id. |
enrichment_id | String | Enrichment job id. |
run_id | String | Source Extract Run id. |
run_started_at | DateTime64(3) | Time the source page was observed. |
product_id | String | Source family key inherited from the Capture. This is not an Extend Product id. |
store_id | String | Deterministic Store key used downstream. |
store_host | String | Source host. |
url | String | Source evidence URL. |
source_title | String | Raw title copied from the Capture. |
product_title, subtitle | String | Enrich-normalized product-family text. |
brand, description | String | Normalized brand and English description. |
vertical_id, category_id | String | Selected taxonomy identifiers. |
category_path | String | Human-readable taxonomy path. |
attributes | JSON-encoded String | Normalized taxonomy attributes. |
signals | JSON-encoded String | Inferred product and merchandising signals. These are not sales or traffic facts. |
image_text | Array(String) | Text evidence extracted from selected images. |
options | JSON-encoded String | Normalized option axes visible on the page. |
publication_date | Nullable(DateTime64(3)) | Parsed source publication date. |
images, videos | Array(String) | Selected media URLs. |
recommended_products | Array(String) | Recommended-product references from the Capture. |
is_brand_source | Bool | Whether the source is treated as brand-owned. |
country | String | Source market country. |
skus | JSON-encoded String | Normalized source SKUs, options, identifiers, media, and embedded commerce observations. |
review_count | UInt32 | Normalized page-level review count. |
review_score | UInt8 | Normalized page-level score on a 0-100 scale. |
The Item API also returns derived summaries such as offer counts and price
ranges. Those values are computed from skus; they are not columns available
to SQL queries. Use the OpenAPI Item schema for the current response fields.
An Item is not a canonical Product, and Enrich does not publish final Offers. Extend resolves Item evidence into the entities below.
changes
Grain: one observed change to one entity aspect.
Identity: id.
Lineage: Run -> observed entity state -> Change.
Use it for: explaining what changed, when it changed, and which state was
replaced.
| Field | SQL type | Meaning |
|---|---|---|
id | UInt64 | Change identifier and query cursor. |
entity | String | Entity scope, such as product, variant, listing, offer, store, or review. |
entity_id | String | Entity id represented consistently as text. |
aspect | String | Changed aspect, such as identity, option, price, availability, stock, seller, store, or review. |
action | String | added, changed, removed, or reappeared. |
run_id | String | Run that produced the observation. |
observed_at | DateTime64(3) | Time the change was observed. |
before, after | JSON-encoded String | Previous and new state for the changed aspect. |
Extend entity model
Extend connects page-grain Items into comparable ecommerce entities:
Product -> Variant -> Listing -> Offer observations
|-> Review aggregate
Store -------------------+Extend and Explore are in beta. The relationships below are useful product semantics, not a promise of unrestricted SQL access to physical tables.
Product
Grain: one normalized product family in an organization dataset.
Identity: Extralt Product id.
Contains: canonical family title, brand, description, taxonomy, attributes,
signals, option axes, and selected media.
Relationship: parent of one or more Variants.
Variant
Grain: one exact canonical configuration under a Product.
Identity: Extralt Variant id; identifiers such as GTIN or MPN when resolved
are evidence, not guaranteed primary keys.
Contains: selected option values, variant media, identifiers, and first-known
time.
Relationship: belongs to one Product and connects equivalent Listings.
Listing
Grain: one source SKU identity in one Store and market.
Identity: Extralt Listing id plus its source SKU evidence.
Contains: source URL, source title, identifiers, media, market, and first,
last, removal, and invalid-status observation times.
Relationship: belongs to one currently resolved Variant and one Store.
Offer
Grain: one observed seller, price, availability, condition, and stock state
for a Listing at one observation time.
Identity: Extralt Offer observation id.
Contains: price, compare-at price, currency, seller, availability, condition,
and categorical stock level.
Relationship: belongs to a Listing and retains Capture and Run lineage.
An Offer is observed evidence, not a continuously synchronized price. A compare-at price can show a visible markdown; it does not prove that a coupon or checkout-only promotion was available.
Review
Grain: latest normalized review aggregate for one Listing and Store.
Contains: review count and score normalized to 0-100.
Does not contain: review text, sentiment, or review history.
Store
Grain: one host and country pair in an organization dataset.
Identity: deterministic Store id referenced by Items, Listings, Offers, and
Reviews.
Contains today: host and country.
A Store is an analytical entity. A Robot is operational extraction tooling for a host and country. They should not be treated as the same object. The current Store model does not claim retailer ownership, company hierarchy, DTC status, traffic, sales, rank, revenue, or turnover.
Interpretation rules
- Identifiers are scoped to the organization's dataset unless the API says otherwise.
- Empty or zero-valued source fields can mean that the source did not expose a fact. Do not turn absence into a measured zero without checking coverage.
- “Current” means the latest observation represented by the product surface, not a continuous market snapshot.
- Prices should be compared within a country and currency unless the calling workflow supplies an explicit conversion source and timestamp.
- Product, Variant, and Listing relationships depend on Extend matching and its available identifiers and evidence.
Continue with query semantics for time, coverage, availability, and current-state rules.