Back to Spree

Relations

docs/api-reference/store-api/relations.mdx

5.4.24.9 KB
Original Source

By default, the Store API returns only the primary resource attributes to keep responses fast and lightweight. Use the expand parameter to expand related resources inline.

Including Relations

Pass a comma-separated list of relation names via the expand query parameter:

<CodeGroup>
typescript
// Product with variants and media
const product = await client.products.get('spree-tote', {
  expand: ['variants', 'media'],
})

// Access included relations directly
console.log(product.variants)  // Array of variant objects
console.log(product.media)     // Array of media objects
bash
curl -G 'http://localhost:3000/api/v3/store/products/spree-tote' \
  -H 'X-Spree-Api-Key: pk_xxx' \
  -d 'expand=variants,media'
</CodeGroup>

Response Format

Without expand, relation fields are omitted from the response:

json
{
  "id": "prod_86Rf07xd4z",
  "name": "Spree Tote",
  "slug": "spree-tote",
  "price": { "amount": "15.99", "currency": "USD" },
  "created_at": "2025-01-15T10:30:00Z"
}

With ?expand=variants,media, the related resources are embedded:

json
{
  "id": "prod_86Rf07xd4z",
  "name": "Spree Tote",
  "slug": "spree-tote",
  "price": { "amount": "15.99", "currency": "USD" },
  "created_at": "2025-01-15T10:30:00Z",
  "variants": [
    {
      "id": "variant_k5nR8xLq",
      "sku": "SPR-TOTE-RED",
      "price": { "amount": "15.99", "currency": "USD" },
      "in_stock": true,
      "option_values": [{ "name": "Red", "option_type_name": "Color" }]
    }
  ],
  "media": [
    {
      "id": "asset_9xPq2wLm",
      "position": 1,
      "alt": "Spree Tote",
      "media_type": "image",
      "product_id": "prod_86Rf07xd4z",
      "variant_ids": ["variant_k5nR8xLq"],
      "original_url": "https://cdn.example.com/spree-tote.jpg",
      "small_url": "https://cdn.example.com/spree-tote-small.jpg",
      "medium_url": "https://cdn.example.com/spree-tote-medium.jpg",
      "large_url": "https://cdn.example.com/spree-tote-large.jpg"
    }
  ]
}

Available Relations by Resource

Products

RelationDescription
variantsAll purchasable variants
default_variantThe default variant
mediaAll product media (images and videos across all variants)
primary_mediaThe main product image
option_typesOption types (e.g., Size, Color)
categoriesCategories this product belongs to
custom_fieldsPublic custom fields (structured metadata)
prior_pricePrevious price history (for showing strikethrough)
<CodeGroup>
typescript
const product = await client.products.get('spree-tote', {
  expand: ['variants', 'media', 'option_types', 'custom_fields'],
})
bash
curl -G 'http://localhost:3000/api/v3/store/products/spree-tote' \
  -H 'X-Spree-Api-Key: pk_xxx' \
  -d 'expand=variants,media,option_types,custom_fields'
</CodeGroup>

Categories

RelationDescription
parentParent category
ancestorsAll ancestor categories (for breadcrumbs)
childrenDirect child categories
custom_fieldsPublic custom fields (structured metadata)
<CodeGroup>
typescript
const category = await client.categories.get('clothing/shirts', {
  expand: ['ancestors', 'children'],
})
bash
curl -G 'http://localhost:3000/api/v3/store/categories/clothing/shirts' \
  -H 'X-Spree-Api-Key: pk_xxx' \
  -d 'expand=ancestors,children'
</CodeGroup>

Countries

RelationDescription
statesStates/provinces within the country
<CodeGroup>
typescript
const usa = await client.countries.get('US', {
  expand: ['states'],
})
console.log(usa.states) // Array of state objects
bash
curl -G 'http://localhost:3000/api/v3/store/countries/US' \
  -H 'X-Spree-Api-Key: pk_xxx' \
  -d 'expand=states'
</CodeGroup>

Collections with Includes

The expand parameter also works on collection endpoints:

<CodeGroup>
typescript
// List products with their media and default variant
const { data: products } = await client.products.list({
  expand: ['media', 'default_variant'],
  limit: 12,
})
bash
curl -G 'http://localhost:3000/api/v3/store/products' \
  -H 'X-Spree-Api-Key: pk_xxx' \
  -d 'expand=media,default_variant' \
  -d 'limit=12'
</CodeGroup>

Nested Includes

Use dot notation to include nested relations:

<CodeGroup>
typescript
// Include variants and their nested option values
const product = await client.products.get('spree-tote', {
  expand: ['variants.option_values'],
})
bash
curl -G 'http://localhost:3000/api/v3/store/products/spree-tote' \
  -H 'X-Spree-Api-Key: pk_xxx' \
  -d 'expand=variants.option_values'
</CodeGroup> <Note> Only include relations you actually need. Each included relation requires additional database queries, so requesting unnecessary relations will slow down the response. </Note>