> ## Documentation Index
> Fetch the complete documentation index at: https://spreecommerce.org/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# List products

> Returns a paginated list of active products for the current store



## OpenAPI

````yaml /api-reference/store.yaml get /api/v3/store/products
openapi: 3.0.3
info:
  title: Store API
  contact:
    name: Spree Commerce
    url: https://spreecommerce.org
    email: hello@spreecommerce.org
  description: >
    Spree Store API v3 - Customer-facing storefront API for building headless
    commerce experiences.


    ## Authentication


    The Store API uses two authentication methods:


    ### API Key (Required)

    All requests must include a publishable API key in the `x-spree-api-key`
    header.


    ### JWT Bearer Token (For authenticated customers)

    After login, include the JWT token in the `Authorization: Bearer <token>`
    header.


    ### Order Token (For guest checkout)

    When creating an order, a `token` is returned. Include this in the
    `x-spree-token` header

    for guest access to that specific order.


    ## Response Format


    All responses are JSON. List endpoints return paginated responses with
    `data` and `meta` keys.


    ## Error Handling


    Errors return a consistent format:

    ```json

    {
      "error": {
        "code": "record_not_found",
        "message": "Product not found"
      }
    }

    ```
  version: v3
servers:
  - url: http://{defaultHost}
    variables:
      defaultHost:
        default: localhost:3000
security: []
tags:
  - name: Authentication
    description: Customer authentication (login, logout, token refresh)
  - name: Product Catalog
    description: Products and categories
  - name: Carts
    description: Shopping cart management
  - name: Orders
    description: Order lookup
  - name: Customers
    description: Customer account, addresses, saved payment methods, and order history
  - name: Markets
    description: Markets, countries, currencies, and locales
  - name: Wishlists
    description: Customer wishlists
  - name: Newsletter Subscribers
    description: Guest and customer newsletter subscriptions (double opt-in)
  - name: Policies
    description: Store policies (return policy, privacy policy, terms of service)
  - name: Digitals
    description: Digital product downloads
paths:
  /api/v3/store/products:
    get:
      tags:
        - Product Catalog
      summary: List products
      description: Returns a paginated list of active products for the current store
      parameters:
        - name: x-spree-api-key
          in: header
          required: true
          description: Publishable API key
          schema:
            type: string
        - name: page
          in: query
          required: false
          description: 'Page number (default: 1)'
          schema:
            type: integer
        - name: limit
          in: query
          required: false
          description: 'Number of items per page (default: 25, max: 100)'
          schema:
            type: integer
        - name: sort
          in: query
          required: false
          description: >-
            Sort order. Prefix with - for descending. Values: price, -price,
            best_selling, name, -name, -available_on, available_on
          schema:
            type: string
        - name: q[name_cont]
          in: query
          required: false
          description: Filter by name containing string
          schema:
            type: string
        - name: q[in_category]
          in: query
          required: false
          description: Filter by category prefixed ID (includes descendants)
          schema:
            type: string
        - name: q[in_categories][]
          in: query
          required: false
          description: >-
            Filter by multiple category prefixed IDs (OR logic, includes
            descendants)
          schema:
            type: string
        - name: q[price_gte]
          in: query
          required: false
          description: Filter by minimum price
          schema:
            type: number
        - name: q[price_lte]
          in: query
          required: false
          description: Filter by maximum price
          schema:
            type: number
        - name: q[with_option_value_ids][]
          in: query
          required: false
          description: >-
            Filter by option value prefix IDs (e.g., optval_abc). Pass multiple
            values for OR logic.
          schema:
            type: string
        - name: q[in_stock]
          in: query
          required: false
          description: Filter to only in-stock products
          schema:
            type: boolean
        - name: expand
          in: query
          required: false
          description: >-
            Comma-separated associations to expand (variants, media, categories,
            option_types)
          schema:
            type: string
        - name: fields
          in: query
          required: false
          description: >-
            Comma-separated list of fields to include (e.g., name,slug,price).
            id is always included.
          schema:
            type: string
      responses:
        '200':
          description: products found
          content:
            application/json:
              example:
                data:
                  - id: prod_UkLWZg9DAJ
                    name: Product 1524935
                    slug: product-1524935
                    meta_title: null
                    meta_description: null
                    meta_keywords: null
                    variant_count: 1
                    available_on: null
                    preorder_ships_at: null
                    purchasable: true
                    preorder: false
                    in_stock: false
                    backorderable: true
                    available: true
                    description: A comfortable cotton t-shirt.
                    description_html: <p>A <strong>comfortable</strong> cotton t-shirt.</p>
                    default_variant_id: variant_gbHJdmfrXB
                    thumbnail_url: null
                    tags: []
                    price:
                      id: price_gbHJdmfrXB
                      amount: '19.99'
                      amount_in_cents: 1999
                      compare_at_amount: null
                      compare_at_amount_in_cents: null
                      currency: USD
                      display_amount: $19.99
                      display_compare_at_amount: null
                      price_list_id: null
                    original_price: null
                  - id: prod_gbHJdmfrXB
                    name: Product 1533120
                    slug: product-1533120
                    meta_title: null
                    meta_description: null
                    meta_keywords: null
                    variant_count: 0
                    available_on: null
                    preorder_ships_at: null
                    purchasable: true
                    preorder: false
                    in_stock: false
                    backorderable: true
                    available: true
                    description: >-
                      Minima error distinctio ducimus quas modi. Veniam beatae
                      adipisci assumenda eveniet voluptatibus. Voluptate
                      accusamus natus non reiciendis doloribus distinctio
                      temporibus nam. Voluptates eaque soluta corrupti quae ex
                      dicta. Voluptatem laudantium dolorum vel laborum sequi
                      dicta. Perferendis consequuntur tempore quibusdam eligendi
                      repellat. Eum qui quae repellendus officiis dolorum culpa.
                    description_html: >-
                      Minima error distinctio ducimus quas modi. Veniam beatae
                      adipisci assumenda eveniet voluptatibus. Voluptate
                      accusamus natus non reiciendis doloribus distinctio
                      temporibus nam. Voluptates eaque soluta corrupti quae ex
                      dicta.

                      Voluptatem laudantium dolorum vel laborum sequi dicta.
                      Perferendis consequuntur tempore quibusdam eligendi
                      repellat. Eum qui quae repellendus officiis dolorum culpa.
                    default_variant_id: variant_EfhxLZ9ck8
                    thumbnail_url: null
                    tags: []
                    price:
                      id: price_EfhxLZ9ck8
                      amount: '19.99'
                      amount_in_cents: 1999
                      compare_at_amount: null
                      compare_at_amount_in_cents: null
                      currency: USD
                      display_amount: $19.99
                      display_compare_at_amount: null
                      price_list_id: null
                    original_price: null
                meta:
                  page: 1
                  limit: 25
                  count: 2
                  pages: 1
                  from: 1
                  to: 2
                  in: 2
                  previous: null
                  next: null
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Product'
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'
                required:
                  - data
                  - meta
        '401':
          description: unauthorized - invalid or missing API key
          content:
            application/json:
              example:
                error:
                  code: invalid_token
                  message: Valid API key required
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - api_key: []
      x-codeSamples:
        - lang: javascript
          label: Spree SDK
          source: |-
            import { createClient } from '@spree/sdk'

            const client = createClient({
              baseUrl: 'https://your-store.com',
              publishableKey: '<api-key>',
            })

            const products = await client.products.list({
              page: 1,
              limit: 25,
              sort: 'price',
              name_cont: 'shirt',
              price_gte: 20,
              price_lte: 100,
              with_option_value_ids: ['optval_abc', 'optval_def'],
              expand: ['variants', 'media'],
            })
components:
  schemas:
    Product:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        slug:
          type: string
        meta_title:
          type: string
          nullable: true
        meta_description:
          type: string
          nullable: true
        meta_keywords:
          type: string
          nullable: true
        variant_count:
          type: number
        available_on:
          type: string
          nullable: true
        preorder_ships_at:
          type: string
          nullable: true
        purchasable:
          type: boolean
        preorder:
          type: boolean
        in_stock:
          type: boolean
        backorderable:
          type: boolean
        available:
          type: boolean
        description:
          type: string
          nullable: true
        description_html:
          type: string
          nullable: true
        default_variant_id:
          type: string
        thumbnail_url:
          type: string
          nullable: true
        tags:
          type: array
          items:
            type: string
        price:
          $ref: '#/components/schemas/Price'
        original_price:
          allOf:
            - $ref: '#/components/schemas/Price'
          nullable: true
        primary_media:
          $ref: '#/components/schemas/Media'
        media:
          type: array
          items:
            $ref: '#/components/schemas/Media'
        variants:
          type: array
          items:
            $ref: '#/components/schemas/Variant'
        default_variant:
          $ref: '#/components/schemas/Variant'
        option_types:
          type: array
          items:
            $ref: '#/components/schemas/OptionType'
        option_values:
          type: array
          items:
            $ref: '#/components/schemas/OptionValue'
        categories:
          type: array
          items:
            $ref: '#/components/schemas/Category'
        custom_fields:
          type: array
          items:
            $ref: '#/components/schemas/CustomField'
        prior_price:
          allOf:
            - $ref: '#/components/schemas/PriceHistory'
          nullable: true
      required:
        - id
        - name
        - slug
        - meta_title
        - meta_description
        - meta_keywords
        - variant_count
        - available_on
        - preorder_ships_at
        - purchasable
        - preorder
        - in_stock
        - backorderable
        - available
        - description
        - description_html
        - default_variant_id
        - thumbnail_url
        - tags
        - price
        - original_price
      x-typelizer: true
    PaginationMeta:
      type: object
      properties:
        page:
          type: integer
          example: 1
        limit:
          type: integer
          example: 25
        count:
          type: integer
          example: 100
          description: Total number of records
        pages:
          type: integer
          example: 4
          description: Total number of pages
        from:
          type: integer
          example: 1
          description: Index of first record on this page
        to:
          type: integer
          example: 25
          description: Index of last record on this page
        in:
          type: integer
          example: 25
          description: Number of records on this page
        previous:
          type: integer
          nullable: true
          example: null
          description: Previous page number
        next:
          type: integer
          nullable: true
          example: 2
          description: Next page number
      required:
        - page
        - limit
        - count
        - pages
        - from
        - to
        - in
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              example: record_not_found
            message:
              type: string
              example: Record not found
            details:
              type: object
              description: Field-specific validation errors
              nullable: true
              example:
                name:
                  - is too short
                  - is required
                email:
                  - is invalid
          required:
            - code
            - message
      required:
        - error
      example:
        error:
          code: validation_error
          message: Validation failed
          details:
            name:
              - is too short
            email:
              - is invalid
    Price:
      type: object
      properties:
        id:
          type: string
        amount:
          type: string
          nullable: true
        amount_in_cents:
          type: number
          nullable: true
        compare_at_amount:
          type: string
          nullable: true
        compare_at_amount_in_cents:
          type: number
          nullable: true
        currency:
          type: string
          nullable: true
        display_amount:
          type: string
          nullable: true
        display_compare_at_amount:
          type: string
          nullable: true
        price_list_id:
          type: string
          nullable: true
      required:
        - id
        - amount
        - amount_in_cents
        - compare_at_amount
        - compare_at_amount_in_cents
        - currency
        - display_amount
        - display_compare_at_amount
        - price_list_id
      x-typelizer: true
    Media:
      type: object
      properties:
        id:
          type: string
        product_id:
          type: string
          nullable: true
        variant_ids:
          type: array
          items:
            type: string
        position:
          type: number
        alt:
          type: string
          nullable: true
        media_type:
          type: string
        focal_point_x:
          type: number
          nullable: true
        focal_point_y:
          type: number
          nullable: true
        external_video_url:
          type: string
          nullable: true
        original_url:
          type: string
          nullable: true
        mini_url:
          type: string
          nullable: true
        small_url:
          type: string
          nullable: true
        medium_url:
          type: string
          nullable: true
        large_url:
          type: string
          nullable: true
        xlarge_url:
          type: string
          nullable: true
        og_image_url:
          type: string
          nullable: true
      required:
        - id
        - product_id
        - variant_ids
        - position
        - alt
        - media_type
        - focal_point_x
        - focal_point_y
        - external_video_url
        - original_url
        - mini_url
        - small_url
        - medium_url
        - large_url
        - xlarge_url
        - og_image_url
      x-typelizer: true
    Variant:
      type: object
      properties:
        id:
          type: string
        product_id:
          type: string
        sku:
          type: string
          nullable: true
        options_text:
          type: string
        track_inventory:
          type: boolean
        media_count:
          type: number
        preorder_ships_at:
          type: string
          nullable: true
        thumbnail_url:
          type: string
          nullable: true
        purchasable:
          type: boolean
        in_stock:
          type: boolean
        backorderable:
          type: boolean
        preorder:
          type: boolean
        weight:
          type: number
          nullable: true
        height:
          type: number
          nullable: true
        width:
          type: number
          nullable: true
        depth:
          type: number
          nullable: true
        price:
          $ref: '#/components/schemas/Price'
        original_price:
          allOf:
            - $ref: '#/components/schemas/Price'
          nullable: true
        primary_media:
          $ref: '#/components/schemas/Media'
        media:
          type: array
          items:
            $ref: '#/components/schemas/Media'
        option_values:
          type: array
          items:
            $ref: '#/components/schemas/OptionValue'
        custom_fields:
          type: array
          items:
            $ref: '#/components/schemas/CustomField'
        prior_price:
          allOf:
            - $ref: '#/components/schemas/PriceHistory'
          nullable: true
      required:
        - id
        - product_id
        - sku
        - options_text
        - track_inventory
        - media_count
        - preorder_ships_at
        - thumbnail_url
        - purchasable
        - in_stock
        - backorderable
        - preorder
        - weight
        - height
        - width
        - depth
        - price
        - original_price
        - option_values
      x-typelizer: true
    OptionType:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        label:
          type: string
        position:
          type: number
        kind:
          type: string
      required:
        - id
        - name
        - label
        - position
        - kind
      x-typelizer: true
    OptionValue:
      type: object
      properties:
        id:
          type: string
        option_type_id:
          type: string
        name:
          type: string
        label:
          type: string
        position:
          type: number
        color_code:
          type: string
          nullable: true
        option_type_name:
          type: string
        option_type_label:
          type: string
        image_url:
          type: string
          nullable: true
      required:
        - id
        - option_type_id
        - name
        - label
        - position
        - color_code
        - option_type_name
        - option_type_label
        - image_url
      x-typelizer: true
    Category:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        permalink:
          type: string
        position:
          type: number
        depth:
          type: number
        meta_title:
          type: string
          nullable: true
        meta_description:
          type: string
          nullable: true
        meta_keywords:
          type: string
          nullable: true
        children_count:
          type: number
        parent_id:
          type: string
          nullable: true
        description:
          type: string
        description_html:
          type: string
        image_url:
          type: string
          nullable: true
        square_image_url:
          type: string
          nullable: true
        is_root:
          type: boolean
        is_child:
          type: boolean
        is_leaf:
          type: boolean
        parent:
          $ref: '#/components/schemas/Category'
        children:
          type: array
          items:
            $ref: '#/components/schemas/Category'
        ancestors:
          type: array
          items:
            $ref: '#/components/schemas/Category'
        custom_fields:
          type: array
          items:
            $ref: '#/components/schemas/CustomField'
      required:
        - id
        - name
        - permalink
        - position
        - depth
        - meta_title
        - meta_description
        - meta_keywords
        - children_count
        - parent_id
        - description
        - description_html
        - image_url
        - square_image_url
        - is_root
        - is_child
        - is_leaf
      x-typelizer: true
    CustomField:
      type: object
      properties:
        id:
          type: string
        label:
          type: string
        type:
          type: string
          deprecated: true
        field_type:
          type: string
          enum:
            - short_text
            - long_text
            - rich_text
            - number
            - boolean
            - json
        key:
          type: string
        value:
          type: object
      required:
        - id
        - label
        - type
        - field_type
        - key
        - value
      x-typelizer: true
    PriceHistory:
      type: object
      properties:
        id:
          type: string
        amount:
          type: string
        amount_in_cents:
          type: number
        currency:
          type: string
        display_amount:
          type: string
        recorded_at:
          type: string
      required:
        - id
        - amount
        - amount_in_cents
        - currency
        - display_amount
        - recorded_at
      x-typelizer: true
  securitySchemes:
    api_key:
      type: apiKey
      name: x-spree-api-key
      in: header
      description: Publishable API key for store access

````