Skip to content

Get product by ID

GET
/products/{productId}
curl --request GET \
--url https://api.example.com/products/example \
--header 'Authorization: Bearer <token>'

Retrieve the full enriched product record by its unique identifier.

productId
required
string

The product record.

Media type application/json

The external product representation — what GET /products/search and GET /products/{productId} return to an M2M caller. This is the FULL contract: every field this schema documents is everything the endpoint can ever return to this caller class. status is internal metadata and deliberately absent, as are the remaining cost/margin fields other than supplierCost — see the “Field Policy” section above.

object
id
string
productCode
string
name
string
description
string
brandName
string
brandSlug
string
range
string
category
string
department
string
subDepartment
string
stockType
string
catalogue
string
displayOnWeb

Whether the product should be published/shown on the consuming integrator’s site (e.g. WooCommerce published vs. draft). For a client bound to a web channel, this is always an explicit true/false reflecting that channel’s visibility. For an unbound client, it reflects the product’s stored visibility flag, which may be omitted when no flag is stored — treat a missing value as not visible.

boolean
notes

Public-facing short description shown to API consumers. Still labelled “Internal Notes” in the CRM UI pending the

string
colour

Product colour/finish.

string
price

Trade selling price.

number
nullable
retailPrice

Recommended retail price (RRP).

number
nullable
supplierCost

Wholesale/cost-basis price. Is returned; treat as commercially sensitive and never expose it to end consumers.

number
nullable
barcode
string
length
number
height
number
width
number
weight
number
weightUnit
string
imageUrl
string
nullable
images
Array<object>
object
url
string format: uri
name
string
documents

Product documents (spec sheets, manuals). Same {url, name} shape as images.

Array<object>
object
url
string format: uri
name
string
createdAt
string format: date-time
erpCode

Supplier/ERP identifier — also what q= search matches for identifier lookups. Used for an ERP catalogue-sync integration.

string
altSupplierCode

Alternate supplier identifier.

string
altSupplierCode2

Second alternate supplier identifier.

string
webHierarchy

Website navigation/category tree path.

string
type

Top-level product classification.

string
subType

Second-level product classification.

string
subSubType

Third-level product classification.

string
retailRange

Product range/collection name shown on the integrator’s site. Distinct from range, which is frequently empty for the same products.

string
relatedProducts

A PROJECTED view of related-items relationships, never the raw persisted shape. productCode/erpCode are inline display fields present ONLY on GET /products/{productId} (enrichment runs before projection there); GET /products/search entries carry only productId/relationType/qty/source. note/name/imageUrl/archived are never present; spares is never exposed at all.

Array<object>
object
productId
required
string format: uuid
productCode

Inline display field — GET /products/{productId} only.

string
erpCode

Inline display field — GET /products/{productId} only.

string
relationType
string
Allowed values: required optional substitute
qty
number
source

Present only on server-derived reverse (used by) entries.

string
Allowed values: reverse
Example
{
"erpCode": "B018704",
"webHierarchy": "Bathrooms;Accessories;Heated Towel Rails",
"retailRange": "Luv",
"relatedProducts": [
{
"relationType": "required",
"source": "reverse"
}
]
}

Authentication required or failed.

Media type application/json
object
error

Machine-readable code. Best-effort — the generic 500 path carries none.

string
message
required
string
requestId

Unique request ID for tracing.

string
nullable
details
object
key
additional properties
any
Example
{
"error": "UNAUTHORIZED",
"message": "Valid authentication token required."
}

Insufficient permissions (missing scope or Admin role).

Media type application/json
object
error

Machine-readable code. Best-effort — the generic 500 path carries none.

string
message
required
string
requestId

Unique request ID for tracing.

string
nullable
details
object
key
additional properties
any
Example
{
"error": "FORBIDDEN",
"message": "Insufficient scope for this operation."
}

Resource not found.

Media type application/json
object
error

Machine-readable code. Best-effort — the generic 500 path carries none.

string
message
required
string
requestId

Unique request ID for tracing.

string
nullable
details
object
key
additional properties
any
Example
{
"error": "NOT_FOUND",
"message": "Product not found"
}