Skip to main content

Products

List Products

const products = await client.products.list({
  page: 1,
  limit: 25,
  expand: ['variants', 'images', 'categories'],
});

Filtering Products

Use flat param keys — the SDK wraps them in q[...] automatically:
const products = await client.products.list({
  name_cont: 'shirt',                                     // Name contains
  price_gte: 20,                                           // Min price
  price_lte: 100,                                          // Max price
  with_option_value_ids: ['optval_abc', 'optval_def'], // By option values
  in_stock: true,                                          // In stock only
  multi_search: 'blue shirt',                              // Full-text search
});

Sorting Products

Pass sort with one of the supported values. Prefix with - for descending order:
const products = await client.products.list({
  sort: 'price',        // price, -price, best_selling,
                         // name, -name, -available_on, available_on
});

Field Selection

Request only specific fields to reduce payload size:
const products = await client.products.list({
  fields: ['name', 'slug', 'price', 'display_price'],
});

const product = await client.products.get('spree-tote', {
  fields: ['name', 'slug', 'price'],
  expand: ['images'],  // expanded associations are always included
});
id is always included. Omit fields to return all fields.

Nested Expand

Use dot notation to expand nested associations (up to 4 levels):
// Expand variants with their images in one request
const product = await client.products.get('spree-tote', {
  expand: ['variants.images', 'option_types'],
});

// Access nested data
product.variants.forEach(variant => {
  console.log(variant.images); // Images are included
});

Get a Product

Fetch a single product by slug or prefix ID:
const product = await client.products.get('spree-tote', {
  expand: ['variants', 'images'],
});

Product Filters

Get available filters (price range, availability, options, categories) and sort options for building filter UIs:
const filters = await client.products.filters({
  category_id: 'ctg_abc123', // Optional: scope filters to a category
});

// Response:
// {
//   filters: [
//     { id: 'price', type: 'price_range', min: 9.99, max: 199.99, currency: 'USD' },
//     { id: 'availability', type: 'availability', options: [{ id: 'in_stock', count: 42 }, ...] },
//     { id: 'opttype_abc', type: 'option', name: 'color', presentation: 'Color', options: [...] },
//     { id: 'categories', type: 'category', options: [{ id: 'ctg_abc', name: 'Shirts', permalink: '...', count: 12 }] },
//   ],
//   sort_options: [{ id: 'manual' }, { id: 'price' }, { id: 'best_selling' }, ...],
//   default_sort: 'manual',
//   total_count: 85,
// }

Categories

List Categories

const categories = await client.categories.list({
  depth_eq: 1,              // Top-level categories only
});

Get a Category

Fetch by ID or permalink:
const category = await client.categories.get('clothing/shirts', {
  expand: ['ancestors', 'children'], // For breadcrumbs and subcategories
});

List Products in a Category

const categoryProducts = await client.categories.products.list('clothing/shirts', {
  page: 1,
  limit: 12,
  expand: ['images', 'default_variant'],
});

Geography

// List countries available for checkout
const { data: countries } = await client.countries.list();

// Get country by ISO code (includes states)
const usa = await client.countries.get('US');
console.log(usa.states); // Array of states