# description
The request body of POST /v1/ingest/batch. A merchant module emits this; the search backend maps it to its canonical model and indexes the result. Generated from the validation rules the endpoint actually enforces — if this schema and the endpoint ever disagree, that is a bug in the generator, not a documentation lag.

# properties.items.description
The batch. Items are applied independently: one malformed item is recorded and skipped, it does not reject the batch.

# $defs.item.properties.op.description
What to do with this object. Absent means "upsert".

# $defs.item.properties.version.description
Your own monotonic clock for this object — milliseconds since epoch is the convention. Last write wins: an item whose version is not greater than the one already indexed is skipped as stale. Send a real, increasing value, or out-of-order delivery will silently overwrite newer data with older.

# $defs.data.properties.id.description
The object id on your platform. Required. Sent back verbatim in the batch response. It is canonicalised to an integer before indexing, so "07" and 7 are the same object — do not rely on a leading zero to distinguish two products.

# $defs.data.properties.object_type.description
What kind of object this is: "product", "page" or "post". Absent means product. An unrecognised but well-formed value is accepted and treated as generic content rather than rejected, so a newer module keeps working against an older backend. Max 20 characters.

# $defs.data.properties.visible.description
Whether shoppers may find this. FAILS CLOSED: anything absent or not explicitly true is unreachable through the public search key. Send true for published, purchasable items only.

# $defs.data.properties.permalink.description
Absolute URL of the item. Only http and https survive; any other scheme is dropped to an empty string rather than indexed.

# $defs.data.properties.image.description
Absolute URL of the thumbnail. Same scheme filtering as permalink.

# $defs.data.properties.categories.description
Category names as a flat list of strings. Note the asymmetry, which is inherited rather than designed: for products the list is taken verbatim (duplicates and blanks preserved); for pages and posts it is filtered to scalars, blanks dropped, and de-duplicated. Send a clean list and the difference cannot affect you.

# $defs.data.properties.description.description
Product description, indexed for search.

# $defs.data.properties.sku.description
The parent SKU. Variant SKUs are unioned into the same searchable field, so a shopper can search any variation code and find the product.

# $defs.data.properties.in_stock.description
Stock status, facetable. Absent is treated as out of stock.

# $defs.data.properties.on_sale.description
Whether the product is currently discounted, facetable.

# $defs.data.properties.popularity_score.description
A ranking hint — typically units sold. Higher sorts earlier when relevance ties. Absent is 0.

# $defs.data.properties.sales_rank.description
DEPRECATED alias for popularity_score, still honoured because the deployed fleet cannot be force-upgraded. New modules must send popularity_score.

# $defs.data.properties.price.description
Price in INTEGER MINOR UNITS — 19.99 USD is 1999, never 19.99. A decimal, a float or a negative value is rejected and the item is not indexed; money is never inferred. With variants, the indexed range is the minimum and maximum across the parent and every variant.

# $defs.data.properties.currency.description
ISO 4217 code, exactly three letters (e.g. "USD", "JPY", "KWD"). Upper-cased on arrival.

# $defs.data.properties.price_exponent.description
How many decimal places your minor units carry: 2 for USD/EUR/GBP, 0 for JPY, 3 for KWD. DECLARE IT. Omitting it means "this producer scaled by 100 whatever the currency", which is what pre-1.x modules did, and reading such a payload as true minor units renders a 1,000 yen product as 100,000 yen. Range 0-4.

# $defs.data.properties.variants.description
Variations, as objects with id, sku, price (integer minor units) and in_stock. NEVER send variants as separate top-level items: one product is one indexed object and one unit of the merchant's quota, however many variations it has. Their SKUs, prices and attributes are folded into the parent.

# $defs.data.properties.attributes.description
Facetable attributes as a map of name to values, e.g. {"Colour": ["Red", "Blue"]}. Attribute NAMES are normalised to a slug, so "Colour Way", "colour-way" and "colour_way" become one facet. Attribute VALUES are NOT normalised — "Red" and "red" stay two distinct facet values, so normalise those yourself. Values from the parent and every variant are unioned and de-duplicated.

# $defs.data.properties.excerpt.description
A short summary for pages and posts. Capped at 1000 characters (characters, not bytes). The page body itself is never indexed.

# $defs.data.properties.published_at.description
Publication time as a Unix timestamp in seconds. Negative values are clamped to 0.