Catalog Data Model
This document defines the customer-facing data model used across REST API, webhooks, MCP, and UCP endpoints.
Product
| Field | Type | Required | Notes |
|---|---|---|---|
id | string | Response only | Internal product UUID. |
catalogId | string | Response only | 10 digit product ID used by cart and agent tools. |
storeId | string | Yes on create | Store UUID in write requests. Responses expose it as scope.storeId. |
scope | object | Response only | Per-product { merchantId, storeId } ownership. It is repeated on every product so multi-merchant and multi-store result sets are unambiguous. |
sku | string | No | Store SKU. Used for idempotent upsert. Max 120 chars. |
externalId | string | No | Source system product ID. Used for idempotent upsert. Max 255 chars. |
name | string | Yes | Product name. Max 255 chars. |
description | string | No | Product description. |
price | number | Yes | Must be 0 or greater. |
currency | string | No | 3-letter currency. Defaults to USD. |
status | string | No | draft, active, or archived. Defaults to active. |
inStock | boolean | No | Defaults to true. |
inventoryQuantity | number | No | Integer, 0 or greater. Defaults to 0. |
imageUrl | string | No | Legacy/public primary image URL. Synchronized with the first imageUrls entry. |
imageUrls | string[] | No | Ordered public image gallery, maximum 20 valid URLs. The first entry is the primary image. |
productUrl | string | No | Public product page URL. |
metadata | object | No | Internal integration metadata. |
otherDetails | object | No | Flexible business attributes. |
variants | array | No | Variant objects. Defaults to []. |
Images are optional. Send imageUrls when a product has a gallery. For backward compatibility, clients may continue sending only imageUrl; when imageUrls is present, its first URL becomes imageUrl. Product snapshots stored in cart items include both fields.
Variant
Variant fields mirror product commercial fields but are stored under the parent product.
| Field | Type | Required |
|---|---|---|
sku | string | No |
externalId | string | No |
name | string | Yes |
description | string | No |
price | number | Yes |
currency | string | No |
status | string | No |
inStock | boolean | No |
inventoryQuantity | number | No |
imageUrl | string | No |
productUrl | string | No |
otherDetails | object | No |
Example:
{
"sku": "HOODIE-BLK-M",
"externalId": "shopify_variant_123",
"name": "Black Hoodie / Medium",
"price": 49.9,
"currency": "USD",
"status": "active",
"inStock": true,
"inventoryQuantity": 8,
"imageUrl": "https://cdn.example.com/hoodie-black-m.png",
"productUrl": "https://store.example.com/products/hoodie?variant=black-m",
"otherDetails": {
"color": "black",
"size": "M"
}
}
Recommended otherDetails
Use otherDetails for structured attributes that do not need dedicated top-level fields.
{
"brand": "Example Brand",
"category": "Apparel",
"tags": ["hoodie", "black", "bestseller"],
"material": "cotton",
"gender": "unisex",
"color": "black",
"sizeSystem": "US",
"fulfillment": {
"warehouse": "east",
"shipsInDays": 2
}
}
Cart
| Field | Type | Notes |
|---|---|---|
id | string | Internal cart UUID. |
scope | object | { merchantId, storeId } ownership of this cart. |
checkout.id | string | Checkout identifier returned after cart creation. |
status | string | open, checkout_created, or completed state when applicable. |
items | array | Cart line items. |
totalQuantity | number | Sum of item quantities. |
totalAmount | string | Total amount as decimal string. |
currency | string | Cart currency. |
metadata | object | Internal metadata. |
otherDetails | object | Channel or agent context. |
Cart item input:
| Field | Type | Required | Notes |
|---|---|---|---|
catalogId | string | Yes | 10 digit product ID. |
quantity | number | Yes | Integer, minimum 1. |
metadata | object | No | Internal metadata. |
otherDetails | object | No | Channel context. |
Order
| Field | Type | Notes |
|---|---|---|
id | string | Internal order UUID. |
orderId | string | Generated public order ID. |
scope | object | { merchantId, storeId } ownership of this order. |
cart.id | string | Source cart UUID. |
checkout.id | string | Checkout ID used to complete the order. |
payment.id | string | Payment ID supplied by the caller or generated internally when omitted. |
customer | object | Customer data. |
shippingAddress | object | Shipping address. |
billingAddress | object | Optional billing address. |
payment | object | Optional on create. A supplied id is preserved; otherwise an internal payment reference is generated. Optional status, when supplied, must be paid. |
status | string | completed or cancelled. |
items | array | Immutable order item snapshots. |
totalQuantity | number | Total item quantity. |
totalAmount | string | Order total. |
currency | string | Order currency. |
metadata | object | Internal metadata. |
otherDetails | object | Integration-specific order data. |
Example customer:
{
"name": "Example User",
"email": "user@example.com",
"phone": "+15551112233"
}
Example address:
{
"line1": "Example Street 1",
"line2": "Apt 4",
"city": "Example City",
"region": "NY",
"country": "US",
"postalCode": "10001"
}
Identity Rules
idis the Thyris product UUID. Use it for direct product updates/deletes after a product has been created.catalogIdis for cart creation and agent tools.skuandexternalIdare used for idempotent product upsert within the same store.- If
skuandexternalIdmatch different products in the same store, the API returns409. - Delete webhook events use
skuand/orexternalId, notcatalogId.