CartistoDocs

Products

List, read, create, and update products over the API.

The Products resource lives at /api/v1/products and requires a key (or session) with the products permission. All responses use the standard envelope.

Endpoints

Method Path Purpose
GET /api/v1/products List products (paginated).
GET /api/v1/products/filter Storefront-style faceted filter.
GET /api/v1/products/:id Read one product.
POST /api/v1/products Create a product.
PUT /api/v1/products/:id Update a product.
DELETE /api/v1/products/:id Soft-delete a product.

List response

{
  "success": true,
  "message": "Products fetched successfully",
  "data": {
    "products": [ /* product objects */ ],
    "pagination": { "page": 1, "limit": 20, "total": 128, "pages": 7 }
  }
}

The product object

Field Type Notes
id string (UUID)
slug string URL slug; unique per store.
sku string | null
barcode string | null
price decimal Base price. Monetary fields are fixed-point decimals — parse as decimal, not float.
compareAtPrice decimal | null “Was” price for a sale.
cost decimal | null Your unit cost — sensitive; only returned to permitted keys, never on the storefront.
categoryId string | null
images string[] Absolute image URLs.
brand string | null
tags string[]
taxExempt boolean
kind enum physical, and digital kinds.
isGiftCard boolean
quantity int Stock on hand (default location).
inventoryTracked boolean
allowBackorder boolean
lowStockThreshold int | null
hasVariants boolean
isActive boolean Published/visible.
publishedAt datetime | null Scheduled-publish time.
averageRating float From approved reviews only.
ratingCount int
createdAt / updatedAt datetime
Note

Names and descriptions are localized A product’s display text is not a flat name field — it lives in a translations array, one entry per language: translations: [{ "language": "en", "name": "…", "description": "…", "slug": "…", "metaTitle": "…", "metaDescription": "…" }]. Read the entry for the language you want; write the same shape on create/update.

Create

A minimal create needs a price and at least one translation:

POST /api/v1/products
{
  "price": 19.90,
  "translations": [
    { "language": "en", "name": "Classic Tee", "description": "100% cotton." }
  ],
  "category": "9d9c…",
  "images": ["https://…/tee.jpg"],
  "quantity": 50
}

For a product with options (size/color), send the option axes under variants and the concrete combinations under productVariants (each with its own price, sku, and quantity). See Products & variants in the merchant docs for the model.

Tip

Deletes are soft DELETE marks a product deleted (freeing its slug) rather than hard-removing it, so order history that references it stays intact.