Skip to content

Product Sub-Resources (Product tag)

Sub-resources of a product — gallery assets, tier prices, customizable options and their pricing/translations, raw EAV values. Most of these are already inlined on the Single Product response; the dedicated endpoints listed here exist when you need just one slice without re-fetching the whole PDP.

URL naming is not uniform

Root URLs in this group use two different separators, so a path cannot be guessed from the resource name:

SeparatorEndpoints
Dashed*-images, *-videos, *-bundle-option-products, *-downloadable-links, *-downloadable-samples
Underscoredproduct_customizable_options, product_customizable_option_prices, product_customizable_option_translations, product_bundle_options, product_grouped_products

The underscored form is the framework's default snake-case route, kept where no explicit path was declared. Copy the URL from the parent resource's IRI rather than assembling it by hand — the IRIs in a response are authoritative.

Endpoints in this group

Images (type = images)

Images come back in gallery order — the order the storefront draws them in, lowest position first, which is also the product's main image. Each carries altText, the description stored for the current locale, and fileName, the file's base name without directory or extension.

MethodPathPurpose
GET/api/shop/products/{productId}/imagesAll images for a product (nested)
GET/api/shop/product-imagesPaginated, every image across the catalog (root)
GET/api/shop/product-images/{id}Single image by global ID

Videos (type = videos)

MethodPathPurpose
GET/api/shop/products/{productId}/videosAll videos for a product (nested)
GET/api/shop/product-videosPaginated root collection
GET/api/shop/product-videos/{id}Single video by global ID

Same response shape as Images, with type: "videos".

Customer Group Prices (tier prices)

MethodPathPurpose
GET/api/shop/products/{productId}/customer-group-pricesTier prices for a product

The nested list is the only tier-price endpoint. There is no single-row route and no root collection — reading one row means reading the product's list and picking it out.

Customizable Options + Prices + Translations

MethodPathPurpose
GET/api/shop/products/{productId}/customizable-optionsAll custom inputs for a product (nested)
GET/api/shop/product_customizable_options/{id}Single option by ID
GET/api/shop/product_customizable_option_pricesPaginated pricing rows
GET/api/shop/product_customizable_option_prices/{id}Single pricing row
GET/api/shop/product_customizable_option_translationsPaginated locale labels
GET/api/shop/product_customizable_option_translations/{id}Single label

Attribute Values (raw EAV — sub-resource only)

MethodPathPurpose
GET/api/shop/products/{productId}/attribute-valuesEvery attribute value row for a product

There is no root collection and no single-row endpoint. Read the values through the product itself.

Response field reference

Image / Video

FieldTypeDescription
idintegerAsset primary key
typestringimages or videos
pathstringStorage path (relative)
productIdintegerOwning product
positionintegerDisplay order
publicPathstringFully-qualified URL

Customer Group Price

FieldTypeDescription
idintegerTier-price row ID
qtynumberThreshold quantity for this tier
valueTypestringfixed (replaces price) or discount (percentage off)
valuenumberTier value — interpreted by valueType
customerGroupIdintegerCustomer group this tier applies to
uniqueIdstringInternal lookup key (<group>|<product>|<qty>)
productIdintegerOwning product

Customizable Option

FieldTypeDescription
idintegerOption primary key
typestringfield, area, drop_down, radio, checkbox, multiple, date, date_time, time, file
isRequiredboolean (0/1)Whether the customer must fill the option
sortOrderintegerDisplay order on the PDP
productstring (IRI)Parent product
pricesarray (IRI)One IRI per pricing row — dereference for the actual prices
translationstring (IRI)Translation for the request locale
translationsarray (IRI)All locale translations

Customizable Option Price

FieldTypeDescription
idintegerPricing row primary key
pricenumberPrice increment for this option
priceTypestringfixed or percent
customizableOptionstring (IRI)Parent customizable option

Customizable Option Translation

FieldTypeDescription
idintegerTranslation row primary key
localestringLocale code
labelstringLocalized option label shown to the customer
customizableOptionstring (IRI)Parent customizable option

Attribute Value

FieldTypeDescription
idintegerEAV row primary key
localestringLocale this value applies to
channelstringChannel code
textValue / integerValue / decimalValue / booleanValue / datetimeValue / dateValue / jsonValuemixedThe typed storage column — only one is populated per row, depending on the attribute's columnName
valuemixedConvenience accessor — same as the populated typed column
uniqueIdstring<channel>|<locale>|<product>|<attribute> — internal index
attributestring (IRI)Parent attribute
productstring (IRI)Parent product

Use Cases

  • Refresh the gallery without re-fetching the entire PDP after the customer changes a configurable variant — GET /api/shop/products/{variantId}/images.
  • Audit assets across the catalog from an admin tool — GET /api/shop/product-images?per_page=50 and walk the pagination.
  • Display tier-price tables on a B2B PDP — GET /api/shop/products/{id}/customer-group-prices.
  • Render a customizable-option editor — list the option from the PDP, then dereference each prices[] IRI for the per-option upcharge.
  • Inspect the raw EAV record during a data-quality audit — GET /api/shop/products/{id}/attribute-values shows exactly what's stored on product_attribute_values.

Released under the MIT License.