> ## 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: 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 1171648
                    slug: product-1171648
                    meta_title: null
                    meta_description: null
                    meta_keywords: null
                    variant_count: 1
                    available_on: '2025-05-13T22:27:20.479Z'
                    purchasable: true
                    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 1189078
                    slug: product-1189078
                    meta_title: null
                    meta_description: null
                    meta_keywords: null
                    variant_count: 0
                    available_on: '2025-05-13T22:27:20.542Z'
                    purchasable: true
                    in_stock: false
                    backorderable: true
                    available: true
                    description: >-
                      Nisi nostrum blanditiis sit reiciendis id dolorum. Rerum
                      consequatur laudantium fugiat corrupti eum atque
                      perspiciatis repellendus. Repellendus eum laborum
                      praesentium totam consequuntur. Dignissimos facere aut
                      eaque suscipit. Sit itaque officiis recusandae tempore
                      libero sapiente laboriosam. Quod quisquam natus deleniti
                      provident et error velit. Veritatis facere temporibus qui
                      maiores quaerat iure aliquid. Iusto repudiandae tenetur
                      assumenda officia occaecati.
                    description_html: >-
                      Nisi nostrum blanditiis sit reiciendis id dolorum. Rerum
                      consequatur laudantium fugiat corrupti eum atque
                      perspiciatis repellendus. Repellendus eum laborum
                      praesentium totam consequuntur.

                      Dignissimos facere aut eaque suscipit. Sit itaque officiis
                      recusandae tempore libero sapiente laboriosam. Quod
                      quisquam natus deleniti provident et error velit.
                      Veritatis facere temporibus qui maiores quaerat iure
                      aliquid. Iusto repudiandae tenetur assumenda officia
                      occaecati.
                    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
        purchasable:
          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'
        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
        - purchasable
        - 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
        thumbnail_url:
          type: string
          nullable: true
        purchasable:
          type: boolean
        in_stock:
          type: boolean
        backorderable:
          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
        - thumbnail_url
        - purchasable
        - in_stock
        - backorderable
        - 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
    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
    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
  securitySchemes:
    api_key:
      type: apiKey
      name: x-spree-api-key
      in: header
      description: Publishable API key for store access

````