Catalog schema
When you upload a catalog via the Dialog API, the JSON must match this schema. Dialog’s AI Assistant uses this structured data to understand your products and recommend accurately.
What Dialog does with the catalog
Section titled “What Dialog does with the catalog”- Understand product features, variants, and specifications.
- Make intelligent product comparisons.
- Provide contextual recommendations based on customer needs.
- Answer detailed questions about your inventory.
The more complete and structured your catalog, the better the answers.
JSON Schema
Section titled “JSON Schema”Paste this into your validator of choice (Ajv, jsonschema, Pydantic via model_json_schema, etc.) to validate your payloads before upload.
{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Dialog product catalog", "type": "object", "required": ["products"], "properties": { "products": { "type": "array", "items": { "$ref": "#/definitions/product" } }, "markets": { "type": "array", "items": { "$ref": "#/definitions/market" }, "description": "Optional. Declare your markets once here, then reference them by `name` from `price.market`. Omit for a single-market catalog." } }, "definitions": { "product": { "type": "object", "required": ["id", "title", "status", "variants", "metafields", "collections", "tags"], "properties": { "id": { "type": "string", "description": "Unique product identifier in your system. Must be stable across imports." }, "title": { "type": "string" }, "url": { "type": "string", "format": "uri", "description": "Canonical product page URL. Used for click-through links in chat recommendations." }, "status": { "$ref": "#/definitions/status" }, "variants": { "type": "array", "minItems": 1, "items": { "$ref": "#/definitions/productVariant" } }, "metafields": { "type": "array", "items": { "$ref": "#/definitions/metafield" } }, "collections": { "type": "array", "items": { "$ref": "#/definitions/collection" } }, "tags": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "translations": { "$ref": "#/definitions/productTranslations" }, "featuredImage": { "$ref": "#/definitions/image" }, "images": { "type": "array", "items": { "$ref": "#/definitions/image" } }, "options": { "type": "array", "items": { "$ref": "#/definitions/option" } } } }, "productVariant": { "type": "object", "required": ["id", "displayName", "inStock", "price"], "properties": { "id": { "type": "string" }, "displayName": { "type": "string" }, "url": { "type": "string", "format": "uri", "description": "Variant-specific page URL. Strongly recommended — chat recommendations link to this URL for in-stock variants. Falls back to the product URL when missing." }, "inStock": { "type": "boolean" }, "price": { "type": "array", "minItems": 1, "items": { "$ref": "#/definitions/price" }, "description": "One entry per market. You can provide one entry without `market` as the default; and `market`-scoped entries for market-specific pricing." }, "translations": { "$ref": "#/definitions/variantTranslations" }, "selectedOptions": { "type": "array", "items": { "$ref": "#/definitions/selectedOption" } }, "metafields": { "type": "array", "items": { "$ref": "#/definitions/metafield" } }, "compareAtPrice": { "type": "array", "items": { "$ref": "#/definitions/price" }, "description": "Original prices, for discount display." }, "image": { "$ref": "#/definitions/image" } } }, "image": { "type": "object", "required": ["url"], "properties": { "url": { "type": "string", "format": "uri", "description": "Direct URL — HTTPS strongly recommended." } } }, "price": { "type": "object", "required": ["amount", "currencyCode"], "properties": { "amount": { "type": "string", "pattern": "^\\d+(\\.\\d+)?$", "description": "Decimal encoded as a string, e.g. \"29.99\". Not a number." }, "currencyCode": { "$ref": "#/definitions/currencyCode" }, "market": { "type": "string", "description": "Optional. Name of a market declared in the top-level `markets`." } } }, "market": { "type": "object", "required": ["name", "countries"], "properties": { "name": { "type": "string", "description": "Unique market name, referenced by `price.market` (e.g. \"Europe\", \"United Kingdom\")." }, "countries": { "type": "array", "minItems": 1, "items": { "type": "string", "pattern": "^[A-Z]{2}$" }, "description": "ISO 3166-1 alpha-2 country codes in this market (e.g. [\"FR\", \"DE\", \"ES\"])." } }, "description": "A market is a group of countries sharing the sames prices and currency" }, "metafield": { "type": "object", "required": ["name", "value"], "properties": { "name": { "type": "string", "description": "e.g. \"material\", \"weight\", \"brand\"." }, "value": { "type": "string", "description": "e.g. \"cotton\", \"2.5kg\", \"Nike\"." } } }, "collection": { "type": "object", "required": ["title"], "properties": { "title": { "type": "string" }, "description": { "type": "string" } } }, "option": { "type": "object", "required": ["id", "name", "values", "position"], "properties": { "id": { "type": "string" }, "name": { "type": "string", "description": "e.g. \"Color\", \"Size\", \"Material\"." }, "values": { "type": "array", "items": { "type": "string" } }, "position": { "type": "integer", "minimum": 0, "description": "0-based display order." }, "translations": { "type": "array", "items": { "$ref": "#/definitions/optionTranslations" } } } }, "selectedOption": { "type": "object", "required": ["name", "value"], "properties": { "name": { "type": "string" }, "value": { "type": "string" }, "translations": { "type": "object", "description": "Map of locale code → translated name/value.", "additionalProperties": { "type": "object", "required": ["name", "value"], "properties": { "name": { "type": "string" }, "value": { "type": "string" } } } } } }, "productTranslations": { "type": "object", "description": "Map of locale code (lowercase ISO, e.g. \"en\", \"fr\") → translated fields.", "additionalProperties": { "type": "object", "required": ["title"], "properties": { "title": { "type": "string" }, "description": { "type": "string" }, "url": { "type": "string", "format": "uri", "description": "Locale-specific product page URL. You can also specify it per variant in `productVariant.translations`." } } } }, "variantTranslations": { "type": "object", "description": "Map of locale code → translated fields.", "additionalProperties": { "type": "object", "required": ["displayName"], "properties": { "displayName": { "type": "string" }, "url": { "type": "string", "format": "uri", "description": "Locale-specific variant page URL." } } } }, "optionTranslations": { "type": "object", "required": ["key", "value"], "properties": { "key": { "type": "string" }, "value": { "type": "string" } } }, "currencyCode": { "type": "string", "enum": ["EUR", "USD", "CAD", "GBP", "PLN"] }, "status": { "type": "string", "enum": ["ACTIVE", "ARCHIVED", "DRAFT", "UNLISTED"], "description": "ACTIVE: available for sale. ARCHIVED: no longer available, kept for reference. DRAFT: not yet ready for sale. UNLISTED: hidden from recommendations." } }}Example payload
Section titled “Example payload”{ "markets": [ { "name": "Europe", "countries": ["FR", "DE", "ES", "IT"] }, { "name": "United Kingdom", "countries": ["GB"] } ], "products": [ { "id": "prod_001", "title": "Premium Cotton T-Shirt", "url": "https://example.com/products/premium-cotton-tshirt", "description": "Comfortable 100% organic cotton t-shirt perfect for everyday wear.", "status": "ACTIVE", "translations": { "fr": { "title": "T-shirt en coton premium", "description": "T-shirt 100% coton biologique, parfait pour tous les jours." } }, "collections": [ { "title": "Summer Collection", "description": "Light and breathable summer essentials" }, { "title": "Eco-Friendly" } ], "tags": ["cotton", "summer", "casual", "organic"], "metafields": [ { "name": "material", "value": "100% Organic Cotton" }, { "name": "care_instructions", "value": "Machine wash cold, tumble dry low" } ], "featuredImage": { "url": "https://example.com/images/tshirt-main.jpg" }, "images": [ { "url": "https://example.com/images/tshirt-front.jpg" }, { "url": "https://example.com/images/tshirt-back.jpg" } ], "options": [ { "id": "color", "name": "Color", "values": ["Red", "Blue", "Green"], "position": 0 }, { "id": "size", "name": "Size", "values": ["S", "M", "L", "XL"], "position": 1 } ], "variants": [ { "id": "var_001", "displayName": "Red T-Shirt - Medium", "url": "https://example.com/products/premium-cotton-tshirt?variant=red-m", "inStock": true, "price": [ { "amount": "29.99", "currencyCode": "USD" }, { "amount": "25.99", "currencyCode": "EUR", "market": "Europe" }, { "amount": "21.99", "currencyCode": "GBP", "market": "United Kingdom" } ], "translations": { "fr": { "displayName": "T-shirt rouge - Taille M" } }, "selectedOptions": [ { "name": "Color", "value": "Red" }, { "name": "Size", "value": "M" } ], "compareAtPrice": [{ "amount": "39.99", "currencyCode": "USD" }], "image": { "url": "https://example.com/images/tshirt-red-m.jpg" } }, { "id": "var_002", "displayName": "Blue T-Shirt - Large", "url": "https://example.com/products/premium-cotton-tshirt?variant=blue-l", "inStock": false, "price": [{ "amount": "29.99", "currencyCode": "USD" }], "selectedOptions": [ { "name": "Color", "value": "Blue" }, { "name": "Size", "value": "L" } ] } ] } ]}Validation tips
Section titled “Validation tips”- The root object must contain
productsas an array. - Every product must have at least one variant.
price.amountis a string, not a number.- Use lowercase ISO codes for locales (
en,fr,es). marketon a price is the name of a market declared in the top-levelmarketsarray — not a country code. Always include onepriceentry withoutmarketas the default.markets[].countriesare uppercase ISO-3166 alpha-2 codes (FR,GB); each country should belong to only one market.urlis strongly recommended on every variant and product — without it, recommendations in the chat cannot link back to your site.
Click-through behavior
Section titled “Click-through behavior”When a shopper clicks a product in the widget, Dialog picks the destination URL in this order:
- The selected variant’s
url(if the variant is known and has one). - The product’s
url.
Always ship at least the product url — and a per-variant url when variants live on distinct pages (e.g. ?variant=red-m).
Upload the file using the pre-signed URL from the API reference.