Skip to main content

Catalog REST API

The REST Catalog API is the primary integration surface for product sync, cart creation, and order completion.

Base URL:

https://merchant.thyris.cloud/api/v1/catalog

All requests require an API key.

Authorization: Bearer tr_live_your_key_here

For a complete required/optional field matrix for each request, see 05-request-field-requirements.md.

Endpoint Summary​

MethodEndpointPurpose
GET/storesList stores available to the API key.
GET/productsList or search products.
GET/product-details?catalogId={catalogId}Get complete authorized product details directly, without ACP Runtime or Flow execution.
POST/productsCreate or upsert a product.
GET/products/{productId}Get one product by Thyris product UUID.
PATCH/products/{productId}Update one product.
DELETE/products/{productId}Delete one product.
GET/cartsList carts. Defaults to non-archived carts. Use status=archived for archived carts.
POST/cartsCreate a checkout-ready cart.
POST / PATCH / DELETE/carts/itemsAdd, update, or remove one or more cart items after cart creation. Supports bundle payloads.
POST/carts/clear?cartId={cartId}Clear a cart if no checkout was created.
POST/carts/archive?cartId={cartId}Permanently archive a cart. Archived carts cannot be reopened.
GET/ordersList orders.
POST/ordersComplete an order from a checkout ID.
GET/orders/{orderId}Get an order by Thyris order UUID, public order ID, or checkout ID.
PATCH/orders/{orderId}Update order details or status.

List Stores​

GET /api/v1/catalog/stores

Optional query:

GET /api/v1/catalog/stores?q=STORE_NAME_OR_ID

List Products​

GET /api/v1/catalog/products?storeId=STORE_UUID&q=hoodie

Query parameters:

NameRequiredNotes
storeIdNoLimits results to one store. Store-scoped keys default to their bound store.
qNoSearches name, SKU, external ID, and catalog ID.

Every returned product carries its own scope: { merchantId, storeId } and public merchant profile. The collection does not publish one root store ID, because merchant-, network-, and custom-scoped keys can return products from multiple stores.

The public merchant profile contains id, name, slug, description, logoUrl, websiteUrl, industry, and language. It intentionally excludes contact details, ownership data, plan, company size, timezone, internal status, and other operational fields. List, search, legacy product lookup, and product-detail responses use the same profile shape.

For the storefront UI profile, every renderable product must have non-empty catalogId, name, price, currency, and primary imageUrl, and its public merchant profile must have non-empty name and logoUrl. websiteUrl is returned when configured but may be null; a merchant website cannot be guaranteed for every merchant. Products or merchants missing an storefront UI-required field must be rejected during onboarding/synchronization or excluded from storefront render results.

Example:

curl "https://merchant.thyris.cloud/api/v1/catalog/products?storeId=STORE_UUID&q=hoodie" \
-H "Authorization: Bearer tr_live_your_key_here"

Create Or Upsert Product​

POST /api/v1/catalog/products
Content-Type: application/json

Required fields:

  • storeId
  • name
  • price

The general Catalog API keeps image fields optional for backward compatibility. Merchants enabled for the storefront UI profile must additionally supply a valid primary imageUrl (directly or as the first imageUrls entry), and the merchant account must have a valid logoUrl.

Recommended idempotency fields:

  • sku
  • externalId

When sku or externalId matches an existing product in the same store, the product is updated. Otherwise a new product is created.

{
"storeId": "STORE_UUID",
"sku": "HOODIE-BLK",
"externalId": "shopify_product_123",
"name": "Black Hoodie",
"description": "A heavyweight black hoodie.",
"price": 49.9,
"currency": "USD",
"status": "active",
"inStock": true,
"inventoryQuantity": 12,
"imageUrl": "https://cdn.example.com/hoodie.png",
"imageUrls": [
"https://cdn.example.com/hoodie.png",
"https://cdn.example.com/hoodie-back.png"
],
"productUrl": "https://store.example.com/products/hoodie",
"metadata": {
"sourceSystem": "shopify"
},
"otherDetails": {
"brand": "Acme",
"category": "Apparel",
"tags": ["hoodie", "black"]
},
"variants": [
{
"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"
}
}
]
}

imageUrls is optional and accepts at most 20 valid URLs in display order. Its first value is the primary image and is synchronized to the legacy imageUrl field. Sending only imageUrl remains supported.

Response:

{
"success": true,
"mode": "created",
"data": {
"id": "product_uuid",
"catalogId": "1234567890"
}
}

Get Product​

GET /api/v1/catalog/products/PRODUCT_UUID

Get Product Details Without A Flow​

GET /api/v1/catalog/product-details?catalogId=1234567890

Use this read-only endpoint when a client already has a product identifier and needs the complete authorized product record without invoking ACP Runtime or selecting a Flow. Prefer the ten-digit catalogId returned by product search. productId, sku, and externalId are also accepted; storeId is recommended with SKU or external-ID lookup.

{
"success": true,
"data": {
"id": "PRODUCT_UUID",
"catalogId": "1234567890",
"name": "Black Hoodie",
"description": "A heavyweight black hoodie.",
"price": "49.90",
"currency": "USD",
"inStock": true,
"imageUrl": "https://cdn.example.com/hoodie.png",
"imageUrls": ["https://cdn.example.com/hoodie.png"],
"store": { "id": "STORE_UUID", "name": "Acme Downtown", "slug": "acme-downtown" },
"merchant": {
"id": "MERCHANT_UUID",
"name": "Acme",
"slug": "acme",
"description": "Apparel and accessories.",
"logoUrl": "https://cdn.example.com/acme-logo.png",
"websiteUrl": "https://acme.example",
"industry": "Retail",
"language": "en"
}
}
}

Update Product​

PATCH /api/v1/catalog/products/PRODUCT_UUID
Content-Type: application/json

Example:

{
"price": 44.9,
"inStock": true,
"inventoryQuantity": 24,
"imageUrls": [
"https://cdn.example.com/hoodie-v2.png",
"https://cdn.example.com/hoodie-v2-back.png"
]
}

If the request only changes price, outbound event subscribers receive product.price.updated. If it changes stock fields, subscribers receive product.inventory.updated. Other product changes emit product.updated.

Delete Product​

DELETE /api/v1/catalog/products/PRODUCT_UUID

Successful response:

{
"success": true
}

List Carts​

GET /api/v1/catalog/carts?storeId=STORE_UUID
GET /api/v1/catalog/carts?storeId=STORE_UUID&status=archived
GET /api/v1/catalog/carts?storeId=STORE_UUID&includeArchived=true

Carts include line items and store summary fields. The default list excludes archived carts so operational cart views do not mix active and archived records. Archived carts are read-only history records.

Create Cart​

POST /api/v1/catalog/carts
Content-Type: application/json

Use the product's 10 digit catalogId, not the product UUID.

{
"storeId": "STORE_UUID",
"items": [
{
"catalogId": "1234567890",
"quantity": 2,
"otherDetails": {
"giftWrap": true
}
}
],
"metadata": {
"conversationId": "conv_123"
},
"otherDetails": {
"channel": "agent"
}
}

Response:

{
"success": true,
"data": {
"id": "cart_uuid",
"scope": {
"merchantId": "MERCHANT_UUID",
"storeId": "STORE_UUID"
},
"checkout": {
"id": "chk_1234567890abcdef12345678"
},
"status": "checkout_created",
"totalQuantity": 2,
"totalAmount": "99.80",
"currency": "USD",
"items": []
}
}

Cart creation fails atomically if a product is inactive, out of stock, has zero inventory, or the requested quantity exceeds stock.

Mutate Cart Items After Creation​

POST /api/v1/catalog/carts/items
PATCH /api/v1/catalog/carts/items
DELETE /api/v1/catalog/carts/items
Content-Type: application/json
Idempotency-Key: merchant-cart-op-001

Single-item payloads remain supported:

{
"cartId": "CART_UUID",
"catalogId": "1234567890",
"quantity": 1
}

Bundle payloads use items[] and apply atomically within one cart mutation. Use POST to add, PATCH to replace quantities, and DELETE to remove lines. Update/remove operations accept either itemId or catalogId for each item.

{
"cartId": "CART_UUID",
"items": [
{ "catalogId": "1234567890", "quantity": 1 },
{ "catalogId": "9876543210", "quantity": 2 }
]
}

Successful mutations return the refreshed cart and emit the specific item or bundle webhook event plus the compatibility cart.updated event. Mutations are rejected when the cart is archived, closed, completed, checkout-locked, outside the key scope, or when inventory is insufficient.

Archive Cart​

POST /api/v1/catalog/carts/archive?cartId=CART_UUID

Archive is irreversible. Archived carts stay available through GET /carts?status=archived and are excluded from the default cart list. Archived carts cannot be changed, cleared, closed, prepared for checkout, or returned to normal cart flow.

Cart And Order Operation Settings​

Merchant Dashboard exposes store-scoped operation settings under Catalog:

  • Cart Settings: open-cart TTL, checkout TTL, abandoned-cart threshold, automatic archive rule set, empty-cart archive threshold, closed/cancelled-checkout archive windows, irreversible archive posture, item/bundle mutation switches, bundle limits, inventory-hold settings, cart export format/schedule/PII inclusion, and cart webhook retry/event toggles.
  • Order Settings: completion mode, manual completion, cancellation/refund windows, dedupe/idempotency policy, stock decrement mode, inventory webhook dispatch, invoice/export format and schedule, retention days, webhook retry/event toggles, and acknowledgement/fulfillment SLA targets.

These settings are stored on the store configuration and are the operational control plane for cart/order behavior. Runtime enforcement depends on the deployed catalog-service version; integration teams should treat dashboard values as authoritative policy and verify enforcement in staging before go-live.

Clear Cart​

POST /api/v1/catalog/carts/clear?cartId=CART_UUID

Carts with an existing checkoutId cannot be cleared.

List Orders​

GET /api/v1/catalog/orders?storeId=STORE_UUID&q=ord_

q searches order ID, checkout ID, and payment ID.

Complete Order​

POST /api/v1/catalog/orders
Content-Type: application/json
{
"checkoutId": "chk_1234567890abcdef12345678",
"payment": {
"id": "pay_1234567890abcdef12345678",
"provider": "manual",
"status": "paid"
},
"customer": {
"name": "Ada Lovelace",
"email": "ada@example.com",
"phone": "+15551112233"
},
"shippingAddress": {
"line1": "Example Street 1",
"city": "New York",
"country": "US",
"postalCode": "10001"
},
"billingAddress": {
"line1": "Example Street 1",
"city": "New York",
"country": "US",
"postalCode": "10001"
},
"otherDetails": {
"deliveryNote": "Leave with reception"
}
}

payment is optional. When payment.id is supplied, the order preserves it for reconciliation; otherwise Catalog generates an internal payment reference. The response contains the newly generated orderId on the order object and returns related IDs as cart.id, checkout.id, and payment.id.

Get Order​

GET /api/v1/catalog/orders/ORDER_ID_OR_CHECKOUT_ID

The path value may be the Thyris order UUID, generated public orderId, or checkoutId.

Update Order​

PATCH /api/v1/catalog/orders/ORDER_ID_OR_CHECKOUT_ID
Content-Type: application/json

Allowed fields:

  • status: completed or cancelled
  • customer
  • shippingAddress
  • billingAddress
  • paymentDetails
  • metadata
  • otherDetails

Example:

{
"status": "cancelled",
"paymentDetails": {
"status": "refunded",
"provider": "manual"
}
}

Common Status Codes​

StatusMeaning
200Successful read or update.
201Created successfully.
400Invalid payload or missing required parameter.
401Missing or invalid API key.
403API key is not allowed to access the requested store or record.
404Product, cart, or order not found.
409Conflict, such as SKU/external ID identity mismatch or invalid cart/order state.
500Unexpected server error.

For retry guidance, outbound receiver responses, and integration checks, see Testing and Troubleshooting and Catalog Webhooks.