ProductsService class (accessed via client.products) reads a store’s catalog: products and their variants, filtering and pagination across them, product specifications, and the collections products are grouped into.
Validation & Rate Limits: Product IDs must be valid UUIDs — malformed IDs return
400 immediately. All endpoints are rate-limited (publishable key: 1,000 requests/hr per IP; secret key: 10,000 requests/hr per key).Product identifier: every product object exposes both
id and product_id. They are the same value — use whichever fits your codebase.Response Structure Tiers
To optimize performance across different device types, the service implements three response tiers:Catalog Discovery
listProducts
Retrieve a paginated list of products. This method returns flat structures (no variants array) to keep payloads small.
- ⚡ Performance: 50-70% smaller than detail endpoints.
- 🖼️ Thumbnails: Use
thumbnail_urlfor fast rendering in lists without iterating arrays. - 🛒 Quick Add: Includes default variant data (
price,stock,sku) at root level. - 🔍 Intelligence: Use the
has_variantsflag to determine if the UI should show “View Options”. - ⏩ Pagination: Uses cursor-based navigation for stable, high-performance scrolling.
Lean by default. The list omits heavy fields a catalog grid rarely needs — the long-form
description, the SEO block (seo_title / seo_description / seo_keywords), raw attributes /
shipping_info, and the full media arrays — so grids stay fast. Get those on the detail calls
(getProduct / getProductBySlug), request them explicitly with fields (e.g.
fields: 'name,price,description,seo_title'), or pass full: true to return the complete object
for every row. thumbnail_url, price, stock, has_variants and the taxonomy fields are always
present.Response
Personalized ordering
Passpersonalize: true together with a signed-in customer’s session token (the x-auth-token
header) and the page is ordered by how closely each product matches that shopper’s preferences,
with the default order as the tiebreak. Without a customer session — or for a shopper who has no
preference signal yet — the order is unchanged, so it is always safe to request.
brand (case-insensitive exact match) to build a brand landing page —
pair it with listBrands below to render a “shop by brand” row, then list the chosen brand’s products:
Filter by category and subcategory
category_id and subcategory_id both match a whole branch of the taxonomy rather than a single
node. A category matches products filed directly against it and products filed under any of its
subcategories, at any depth; a subcategory matches products filed against it and every nested
subcategory beneath it. A category page therefore returns the products of the branch as a shopper
understands it — a “Computers” category includes everything under “Laptops” without listing each
subcategory separately.
products array with a
200, not an error. The two filters can be combined, in which case a product must match both.
The subcategories of a category are available from GET /v1/subcategories?category_id=….
Several ids in one request. Both parameters accept multiple ids, in three forms:
Passing several ids to one request keeps a single pagination cursor valid across the combined set.
One request per category yields a separate cursor per response, and those cursors cannot be merged
into a coherent page 2 — so a landing page spanning several categories is built from one multi-id
request, not from several single-id requests stitched together.
listBrands
Return the catalog’s distinct brands, each with a product count, sorted by count (most products
first). Use it to build brand navigation — for example a “featured brands” row after the hero — then
pass a chosen brand to listProducts({ brand }).
Response
storeId
to scope to one merchant.
getProduct
Retrieve complete details for a single item. This method handles Multi-Variant products by returning a hierarchical structure that eliminates data redundancy and supports variant-aware media.
- Product-Level: Shared metadata at the root (name, brand, media gallery).
- Aggregate Data:
total_stock(sum of all variants) andprice_range(min/maxusingselling_price). - Variants Array: Clean array containing variant-specific attributes (color, size, SKU) and isolated media for that specific variation.
price_range / total_stock and a clean variants[]
array, each with its own SKU, attributes, and isolated media:
Response
getProductBySlug
Retrieve a product using its SEO-friendly slug. Identical to getProduct in response structure but optimized for PDP routing.
SEO metadata
Every product carries optional SEO metadata for rendering search-engine-friendly product detail pages:seo_title— the<title>for the product page.seo_description— the meta description.seo_keywords— an array of keywords.
📸 Media Gallery System
The media system supports a fully-functional, variant-aware gallery.Root-Level Media
thumbnail_url: Represents the primary image for the product. Perfect for simple grids.media: An array of objects containing all base-level images and videos.
Variant Media
Each variant in thevariants[] array can have its own media array. This allows you to show specific images when a user selects a particular variation (e.g., rotating the gallery to show the “Midnight Blue” model).
Media Object Structure:
🎨 Advanced Field Filtering
Tybrite supports powerful field selection to minimize bandwidth.Root-Level Filtering
Exclude large metadata objects by selecting only top-level fields.Nested Array Filtering
Use dot notation to select specific fields within nested arrays.- Core:
product_id,name,sku,description,thumbnail_url,media - Pricing:
price,selling_price,sale_price,price_range - Inventory:
stock,total_stock,last_restocked(last_restockedis not returned by default — request it explicitly) - Variants:
variants.sku,variants.selling_price,variants.media,variants.variant_attributes
Product Specifications
getProductSpecifications
Retrieve the latest published specifications for a single variant. Specifications are stored per
variant, so pass a variant id (e.g. a variant_id from getProduct().variants[]) — not a
product id. A product id returns 404.
Response
Returns
404 (“No specifications found for this product”) if the variant has no published
specification — or if you passed a product id instead of a variant id. To browse all specs across
the catalog (each tagged with its variant_id), use listProductSpecifications.getProductCustomFields
Retrieve the merchant’s own custom fields for a product. A merchant can define fields Galactic Core does
not — a care instruction, a country of origin, a fabric composition — and fill them per product.
Only fields the merchant published are returned. A custom field can hold a cost or an internal reference,
so a field is private unless it is explicitly marked public, and a private field is absent rather than
empty. A product with no published fields returns an empty array.
Response
field_type tells you the shape of value: multiselect is an array of strings, json,
dimensions and weight are objects, and the rest are scalars — a number field arrives as a number,
not as text. field_label is what the merchant calls the field and is the string to show; field_name
is stable across label edits and is the one to key off in code.
value is null when the merchant defined a field but has not filled it for this product, which is
distinct from the field not existing.listProductSpecifications
Browse specifications across the catalog rather than fetching one variant’s. Useful for building a
spec-driven filter (every value of “storage_type” in stock, say) without a request per variant.
Response
Each entry carries its own
variant_id, so a single pass over the list can be grouped by variant
without further lookups.
Collections
Curated groups of products a merchant highlights on their storefront — a “Featured”, “New Arrivals”, or “Summer Edit” row. Each collection can carry a banner image, which makes it a natural building block for an image-led homepage.listProductCollections
Response
image is the collection’s banner and the image to use on every viewport; image_mobile is an optional phone-sized crop. Render the mobile image on small screens when it is set and fall back to image otherwise — a <picture> element with a mobile <source> handles this cleanly. Either field is null when the merchant has not added artwork.
getProductCollection
Fetch a single collection by id — the same shape listProductCollections returns for that entry,
so use it when you land directly on a collection page and have only the id from the URL. A
collection the merchant built from rules rather than by hand also carries those rules.
Response
rules describes how an automated or smart collection selects its products, and is null for a
collection the merchant curated by hand.
Returns 404 when no collection matches the id.
getProductCollectionItems
Response
{ "items": [] }.
Response Codes
All product endpoints areGET and accept both publishable and secret keys.

