docs/api-reference/store-api/relations.mdx
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.
Pass a comma-separated list of relation names via the expand query parameter:
// 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
curl -G 'http://localhost:3000/api/v3/store/products/spree-tote' \
-H 'X-Spree-Api-Key: pk_xxx' \
-d 'expand=variants,media'
Without expand, relation fields are omitted from the response:
{
"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:
{
"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"
}
]
}
| Relation | Description |
|---|---|
variants | All purchasable variants |
default_variant | The default variant |
media | All product media (images and videos across all variants) |
primary_media | The main product image |
option_types | Option types (e.g., Size, Color) |
categories | Categories this product belongs to |
custom_fields | Public custom fields (structured metadata) |
prior_price | Previous price history (for showing strikethrough) |
const product = await client.products.get('spree-tote', {
expand: ['variants', 'media', 'option_types', 'custom_fields'],
})
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'
| Relation | Description |
|---|---|
parent | Parent category |
ancestors | All ancestor categories (for breadcrumbs) |
children | Direct child categories |
custom_fields | Public custom fields (structured metadata) |
const category = await client.categories.get('clothing/shirts', {
expand: ['ancestors', 'children'],
})
curl -G 'http://localhost:3000/api/v3/store/categories/clothing/shirts' \
-H 'X-Spree-Api-Key: pk_xxx' \
-d 'expand=ancestors,children'
| Relation | Description |
|---|---|
states | States/provinces within the country |
const usa = await client.countries.get('US', {
expand: ['states'],
})
console.log(usa.states) // Array of state objects
curl -G 'http://localhost:3000/api/v3/store/countries/US' \
-H 'X-Spree-Api-Key: pk_xxx' \
-d 'expand=states'
The expand parameter also works on collection endpoints:
// List products with their media and default variant
const { data: products } = await client.products.list({
expand: ['media', 'default_variant'],
limit: 12,
})
curl -G 'http://localhost:3000/api/v3/store/products' \
-H 'X-Spree-Api-Key: pk_xxx' \
-d 'expand=media,default_variant' \
-d 'limit=12'
Use dot notation to include nested relations:
<CodeGroup>// Include variants and their nested option values
const product = await client.products.get('spree-tote', {
expand: ['variants.option_values'],
})
curl -G 'http://localhost:3000/api/v3/store/products/spree-tote' \
-H 'X-Spree-Api-Key: pk_xxx' \
-d 'expand=variants.option_values'