RetailLink

Object

Merchant API

product

A product in the shop catalogue.

A product is the parent catalogue record merchants edit in Admin → Products. It groups one or more variants (the sellable SKUs with price, barcode, and inventory). The Merchant API returns products for sync, PIM, and middleware. POS and Storefront read the same underlying catalogue — so an ACTIVE product with stock can be scanned on the till and purchased online when channels allow.

Exposure

Returned by Merchant API list/detail routes for this resource.

What

The product object is the JSON / domain shape for this resource in RetailLink.

Why

Use these fields when integrating — not scraped Admin HTML — so sync jobs and apps stay stable across UI changes.

How

Read each property below — description first, then that property's Code / Data / Output (or type). Use the sticky example JSON on the right as a full fixture.

Properties

9 fields on product. Types link to related objects when available. Snippets for a property appear under that property.

id

string

Stable unique identifier for the product within the shop. Use this id in GET /products/{id}, webhooks, and foreign keys in your integration — not the human title.

Type
id: string

title

string

Merchant-facing display name shown in Admin, on receipts/line descriptions when mapped from the product, and typically on the storefront PDP. Changing the title does not change the id; the handle may be regenerated only on create collisions.

const title = product.title;

handle

string

URL-safe unique slug within the shop (lowercase, hyphenated). Generated from the title on create when not supplied. Used for storefront-style paths and as a stable human-readable key alongside id.

Tip · Prefer id for API joins; use handle when building customer-facing URLs.

Type
handle: string

status

ProductStatus

Lifecycle flag. DRAFT is work-in-progress and should not be sold. ACTIVE is eligible to sell on channels that include the product. ARCHIVED hides the product from day-to-day selling while retaining history.

Note · Channel rules and inventory still apply — ACTIVE with zero stock may be non-sellable depending on policy.

Type
status: DRAFT | ACTIVE | ARCHIVED

description

string | null

Long-form body copy for the product (often HTML or rich text from Admin). Null when the merchant has not written a description. Storefront themes render this on the product page; POS generally does not show it on the till grid.

Type
description: string | null

tags

array of string

Free-form labels for merchandising, search, and your own automation rules (e.g. outdoor, clearance). Returned on single-product fetches so integrations can segment catalogues without a separate taxonomy API.

Note · Included on GET /products/{id}; list responses may omit tags to keep payloads small.

Type
tags: string[]

createdAt

string

ISO-8601 timestamp when the product row was first created in the shop database. Useful for incremental sync watermarks and audit UIs.

Tip · Format with your locale date helpers when displaying to merchants.

Type
createdAt: string

updatedAt

string

ISO-8601 timestamp of the last product-level update. Poll or webhook on product.updated to keep external systems current; variant-only stock moves may also bump related timestamps depending on write path.

Type
updatedAt: string

variants

array of variant

Array of sellable variants. Even “simple” products have at least one variant (often titled Default Title) that carries sku, barcode, price, and inventoryQuantity — those are what POS scans and what checkout decrements.

Tip · Always treat variants as the unit of sale; never assume a product has a top-level price field in the API.

const skus = product.variants.map((v) => v.sku);