Spree Commerce Products API

Products, taxons/categories, product custom field values, and bulk product operations

OpenAPI Specification

spree-products-api-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: Admin Account / Address Products API
  contact:
    name: Spree Commerce
    url: https://spreecommerce.org
    email: hello@spreecommerce.org
  description: "Spree Admin API v3 - Administrative API for managing products, orders, and store settings.\n\n## Authentication\n\nThe Admin API requires a secret API key passed in the `x-spree-api-key` header.\nSecret API keys can be generated in the Spree admin dashboard.\n\n## Response Format\n\nAll responses are JSON. List endpoints return paginated responses with `data` and `meta` keys.\nSingle resource endpoints return a flat JSON object.\n\n## Resource IDs\n\nEvery resource is identified by an opaque string ID (e.g. `prod_86Rf07xd4z`,\n`variant_k5nR8xLq`, `or_UkLWZg9DAJ`). Use these IDs everywhere — URL paths,\nrequest bodies, and Ransack filters all accept them directly.\n\n## Error Handling\n\nErrors return a consistent format:\n```json\n{\n  \"error\": {\n    \"code\": \"validation_error\",\n    \"message\": \"Validation failed\",\n    \"details\": { \"name\": [\"can't be blank\"] }\n  }\n}\n```\n"
  version: v3
servers:
- url: http://{defaultHost}
  variables:
    defaultHost:
      default: localhost:3000
tags:
- name: Products
  description: Products, taxons/categories, product custom field values, and bulk product operations
paths:
  /api/v3/admin/products/{product_id}/custom_fields:
    get:
      summary: List product custom fields
      tags:
      - Products
      security:
      - api_key: []
        bearer_auth: []
      description: 'Returns the product''s custom field values.


        **Required scope:** `read_products` (for API-key authentication).'
      x-codeSamples:
      - lang: javascript
        label: Spree Admin SDK
        source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n  baseUrl: 'https://your-store.com',\n  secretKey: 'sk_xxx',\n})\n\nconst { data: customFields } = await client.products.customFields.list('prod_UkLWZg9DAJ')"
      parameters:
      - name: x-spree-api-key
        in: header
        required: true
        schema:
          type: string
      - name: Authorization
        in: header
        required: true
        schema:
          type: string
      - name: product_id
        in: path
        required: true
        schema:
          type: string
      - name: expand
        in: query
        required: false
        description: Comma-separated associations to expand (e.g., custom_field_definition). Use dot notation for nested expand (max 4 levels).
        schema:
          type: string
      - name: fields
        in: query
        required: false
        description: Comma-separated list of fields to include (e.g., key,value,namespace). id is always included.
        schema:
          type: string
      responses:
        '200':
          description: custom fields found
          content:
            application/json:
              example:
                data:
                - id: cf_UkLWZg9DAJ
                  label: Title
                  type: Spree::Metafields::ShortText
                  field_type: short_text
                  key: custom.title
                  value: wool
                  created_at: '2026-06-12T17:25:00.143Z'
                  updated_at: '2026-06-12T17:25:00.143Z'
                  storefront_visible: true
                  custom_field_definition_id: cfdef_UkLWZg9DAJ
                meta:
                  page: 1
                  limit: 25
                  count: 1
                  pages: 1
                  from: 1
                  to: 1
                  in: 1
                  previous: null
                  next: null
    post:
      summary: Create a product custom field
      tags:
      - Products
      security:
      - api_key: []
        bearer_auth: []
      description: 'Sets a custom field value on the product. Requires an existing CustomFieldDefinition; pass its prefixed `cfdef_…` id.


        **Required scope:** `write_products` (for API-key authentication).'
      x-codeSamples:
      - lang: javascript
        label: Spree Admin SDK
        source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n  baseUrl: 'https://your-store.com',\n  secretKey: 'sk_xxx',\n})\n\nconst customField = await client.products.customFields.create('prod_UkLWZg9DAJ', {\n  custom_field_definition_id: 'cfdef_AbC123XyZ',\n  value: 'wool',\n})"
      parameters:
      - name: x-spree-api-key
        in: header
        required: true
        schema:
          type: string
      - name: Authorization
        in: header
        required: true
        schema:
          type: string
      - name: product_id
        in: path
        required: true
        schema:
          type: string
      responses:
        '201':
          description: custom field created
          content:
            application/json:
              example:
                id: cf_gbHJdmfrXB
                label: Description
                type: Spree::Metafields::LongText
                field_type: long_text
                key: custom.description
                value: A longer description
                created_at: '2026-06-12T17:25:00.791Z'
                updated_at: '2026-06-12T17:25:00.791Z'
                storefront_visible: true
                custom_field_definition_id: cfdef_gbHJdmfrXB
        '422':
          description: duplicate definition for the same product
          content:
            application/json:
              example:
                error:
                  code: validation_error
                  message: Metafield definition has already been taken
                  details:
                    metafield_definition_id:
                    - has already been taken
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
              - custom_field_definition_id
              - value
              properties:
                custom_field_definition_id:
                  type: string
                  description: Prefixed `cfdef_…` id
                value:
                  description: Value matching the definition's `field_type`
  /api/v3/admin/products/{product_id}/custom_fields/{id}:
    get:
      summary: Show a product custom field
      tags:
      - Products
      security:
      - api_key: []
        bearer_auth: []
      description: '**Required scope:** `read_products` (for API-key authentication).'
      parameters:
      - name: x-spree-api-key
        in: header
        required: true
        schema:
          type: string
      - name: Authorization
        in: header
        required: true
        schema:
          type: string
      - name: product_id
        in: path
        required: true
        schema:
          type: string
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: expand
        in: query
        required: false
        description: Comma-separated associations to expand (e.g., custom_field_definition). Use dot notation for nested expand (max 4 levels).
        schema:
          type: string
      - name: fields
        in: query
        required: false
        description: Comma-separated list of fields to include (e.g., key,value,namespace). id is always included.
        schema:
          type: string
      responses:
        '200':
          description: custom field found
          content:
            application/json:
              example:
                id: cf_UkLWZg9DAJ
                label: Title
                type: Spree::Metafields::ShortText
                field_type: short_text
                key: custom.title
                value: wool
                created_at: '2026-06-12T17:25:01.167Z'
                updated_at: '2026-06-12T17:25:01.167Z'
                storefront_visible: true
                custom_field_definition_id: cfdef_UkLWZg9DAJ
    patch:
      summary: Update a product custom field
      tags:
      - Products
      security:
      - api_key: []
        bearer_auth: []
      description: 'Updates the custom field''s `value`. The linked definition cannot be changed — delete and recreate to switch.


        **Required scope:** `write_products` (for API-key authentication).'
      parameters:
      - name: x-spree-api-key
        in: header
        required: true
        schema:
          type: string
      - name: Authorization
        in: header
        required: true
        schema:
          type: string
      - name: product_id
        in: path
        required: true
        schema:
          type: string
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: custom field updated
          content:
            application/json:
              example:
                id: cf_UkLWZg9DAJ
                label: Title
                type: Spree::Metafields::ShortText
                field_type: short_text
                key: custom.title
                value: cotton
                created_at: '2026-06-12T17:25:01.494Z'
                updated_at: '2026-06-12T17:25:01.792Z'
                storefront_visible: true
                custom_field_definition_id: cfdef_UkLWZg9DAJ
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
              - value
              properties:
                value:
                  description: New value
    delete:
      summary: Delete a product custom field
      tags:
      - Products
      security:
      - api_key: []
        bearer_auth: []
      description: '**Required scope:** `write_products` (for API-key authentication).'
      parameters:
      - name: x-spree-api-key
        in: header
        required: true
        schema:
          type: string
      - name: Authorization
        in: header
        required: true
        schema:
          type: string
      - name: product_id
        in: path
        required: true
        schema:
          type: string
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        '204':
          description: custom field deleted
  /api/v3/admin/products:
    get:
      summary: List products
      tags:
      - Products
      security:
      - api_key: []
        bearer_auth: []
      description: 'Returns a paginated list of products for the current store.


        **Required scope:** `read_products` (for API-key authentication).'
      x-codeSamples:
      - lang: javascript
        label: Spree Admin SDK
        source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n  baseUrl: 'https://your-store.com',\n  secretKey: 'sk_xxx',\n})\n\nconst { data: products } = await client.products.list({\n  name_cont: 'shirt',\n  status_eq: 'active',\n  sort: '-created_at',\n  limit: 25,\n})"
      parameters:
      - name: x-spree-api-key
        in: header
        required: true
        schema:
          type: string
      - name: Authorization
        in: header
        required: true
        description: Bearer token for admin authentication
        schema:
          type: string
      - name: page
        in: query
        required: false
        description: Page number
        schema:
          type: integer
      - name: limit
        in: query
        required: false
        description: Number of records per page
        schema:
          type: integer
      - name: sort
        in: query
        required: false
        description: Sort field (e.g., name, -name, price, -price, best_selling)
        schema:
          type: string
      - name: expand
        in: query
        required: false
        description: Comma-separated associations to expand (e.g., variants, media, option_types, categories). Use dot notation for nested expand (max 4 levels).
        schema:
          type: string
      - name: fields
        in: query
        required: false
        description: Comma-separated list of fields to include (e.g., name,slug,price,status). id is always included.
        schema:
          type: string
      - name: q[name_cont]
        in: query
        required: false
        description: Filter by name (contains)
        schema:
          type: string
      - name: q[status_eq]
        in: query
        required: false
        description: Filter by status
        schema:
          type: string
      responses:
        '200':
          description: products found
          content:
            application/json:
              example:
                data:
                - id: prod_UkLWZg9DAJ
                  name: Product 572113
                  slug: product-572113
                  meta_title: null
                  meta_description: null
                  meta_keywords: null
                  variant_count: 0
                  available_on: null
                  purchasable: true
                  in_stock: false
                  backorderable: true
                  available: true
                  description: Optio eum culpa id nostrum aspernatur tenetur asperiores. Qui quos quod laudantium tempora sequi. Adipisci sequi neque commodi tenetur. Veritatis doloremque fugiat quae accusantium inventore perferendis provident laudantium. Similique officiis quasi saepe reiciendis quam molestias.
                  description_html: Optio eum culpa id nostrum aspernatur tenetur asperiores. Qui quos quod laudantium tempora sequi. Adipisci sequi neque commodi tenetur. Veritatis doloremque fugiat quae accusantium inventore perferendis provident laudantium. Similique officiis quasi saepe reiciendis quam molestias.
                  default_variant_id: variant_UkLWZg9DAJ
                  thumbnail_url: null
                  tags: []
                  price:
                    id: price_UkLWZg9DAJ
                    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
                    variant_id: variant_UkLWZg9DAJ
                    created_at: '2026-06-12T17:25:02.180Z'
                    updated_at: '2026-06-12T17:25:02.180Z'
                  original_price: null
                  status: active
                  metadata: {}
                  deleted_at: null
                  created_at: '2026-06-12T17:25:02.168Z'
                  updated_at: '2026-06-12T17:25:02.188Z'
                  tax_category_id: taxcat_UkLWZg9DAJ
                meta:
                  page: 1
                  limit: 25
                  count: 1
                  pages: 1
                  from: 1
                  to: 1
                  in: 1
                  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
          content:
            application/json:
              example:
                error:
                  code: authentication_required
                  message: Authentication required
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    post:
      summary: Create a product
      tags:
      - Products
      security:
      - api_key: []
        bearer_auth: []
      description: 'Creates a new product. Supports nested variants with prices and option types.


        Option types and values are auto-created if they don''t exist.

        Prices are upserted by currency. Stock items are upserted by stock location.



        **Required scope:** `write_products` (for API-key authentication).'
      x-codeSamples:
      - lang: javascript
        label: Spree Admin SDK
        source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n  baseUrl: 'https://your-store.com',\n  secretKey: 'sk_xxx',\n})\n\nconst product = await client.products.create({\n  name: 'Premium T-Shirt',\n  description: 'Soft, organic cotton.',\n  status: 'active',\n  variants: [\n    {\n      sku: 'TSHIRT-S-NAVY',\n      options: [\n        { name: 'size', value: 'Small' },\n        { name: 'color', value: 'navy' },\n      ],\n      prices: [\n        { currency: 'USD', amount: 29.99 },\n        { currency: 'EUR', amount: 27.99 },\n      ],\n      stock_items: [\n        { stock_location_id: 'sloc_UkLWZg9DAJ', count_on_hand: 50 },\n      ],\n    },\n    {\n      sku: 'TSHIRT-M-NAVY',\n      options: [\n        { name: 'size', value: 'Medium' },\n        { name: 'color', value: 'navy' },\n      ],\n      prices: [{ currency: 'USD', amount: 29.99 }],\n      stock_items: [\n        { stock_location_id: 'sloc_UkLWZg9DAJ', count_on_hand: 30 },\n      ],\n    },\n  ],\n})"
      parameters:
      - name: x-spree-api-key
        in: header
        required: true
        schema:
          type: string
      - name: Authorization
        in: header
        required: true
        description: Bearer token for admin authentication
        schema:
          type: string
      responses:
        '201':
          description: product created
          content:
            application/json:
              example:
                id: prod_gbHJdmfrXB
                name: New Product
                slug: new-product
                meta_title: null
                meta_description: null
                meta_keywords: null
                variant_count: 0
                available_on: null
                purchasable: false
                in_stock: false
                backorderable: false
                available: false
                description: null
                description_html: null
                default_variant_id: variant_gbHJdmfrXB
                thumbnail_url: null
                tags: []
                price: null
                original_price: null
                status: draft
                metadata: {}
                deleted_at: null
                created_at: '2026-06-12T17:25:02.877Z'
                updated_at: '2026-06-12T17:25:02.878Z'
                tax_category_id: null
              schema:
                $ref: '#/components/schemas/Product'
        '422':
          description: validation error
          content:
            application/json:
              example:
                error:
                  code: validation_error
                  message: Name can't be blank
                  details:
                    name:
                    - can't be blank
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  example: Premium T-Shirt
                description:
                  type: string
                slug:
                  type: string
                status:
                  type: string
                  enum:
                  - draft
                  - active
                  - archived
                tax_category_id:
                  type: string
                  description: Tax category ID
                category_ids:
                  type: array
                  items:
                    type: string
                  description: Array of category IDs
                tags:
                  type: array
                  items:
                    type: string
                  example:
                  - eco
                  - sale
                variants:
                  type: array
                  description: Array of variant payloads. Variants can declare multiple option pairs via `options:` and per-currency prices via `prices:`. Stock counts go in `stock_items:` (per stock location).
                  items:
                    type: object
                    properties:
                      sku:
                        type: string
                      options:
                        type: array
                        description: One pair per option type the variant participates in (e.g. size + color). Option types and values are auto-created if missing.
                        items:
                          type: object
                          required:
                          - name
                          - value
                          properties:
                            name:
                              type: string
                              example: size
                            value:
                              type: string
                              example: Small
                      prices:
                        type: array
                        description: Per-currency prices. Upserted by currency.
                        items:
                          type: object
                          required:
                          - currency
                          - amount
                          properties:
                            currency:
                              type: string
                              example: USD
                            amount:
                              type: number
                              example: 29.99
                            compare_at_amount:
                              type: number
                              example: 39.99
                      stock_items:
                        type: array
                        description: Per-stock-location inventory. Upserted by stock_location_id.
                        items:
                          type: object
                          required:
                          - stock_location_id
                          - count_on_hand
                          properties:
                            stock_location_id:
                              type: string
                              description: Stock location ID (e.g. sloc_xxx)
                            count_on_hand:
                              type: integer
                              example: 50
                            backorderable:
                              type: boolean
              required:
              - name
  /api/v3/admin/products/{id}:
    get:
      summary: Get a product
      tags:
      - Products
      security:
      - api_key: []
        bearer_auth: []
      description: 'Returns a single product by ID.


        **Required scope:** `read_products` (for API-key authentication).'
      x-codeSamples:
      - lang: javascript
        label: Spree Admin SDK
        source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n  baseUrl: 'https://your-store.com',\n  secretKey: 'sk_xxx',\n})\n\nconst product = await client.products.get('prod_86Rf07xd4z', {\n  expand: ['variants', 'option_types'],\n})"
      parameters:
      - name: x-spree-api-key
        in: header
        required: true
        schema:
          type: string
      - name: Authorization
        in: header
        required: true
        description: Bearer token for admin authentication
        schema:
          type: string
      - name: id
        in: path
        required: true
        description: Product ID (e.g., prod_xxx)
        schema:
          type: string
      - name: expand
        in: query
        required: false
        description: Comma-separated associations to expand (e.g., variants, media, option_types, categories). Use dot notation for nested expand (max 4 levels).
        schema:
          type: string
      - name: fields
        in: query
        required: false
        description: Comma-separated list of fields to include (e.g., name,slug,price,status). id is always included.
        schema:
          type: string
      responses:
        '200':
          description: product found
          content:
            application/json:
              example:
                id: prod_UkLWZg9DAJ
                name: Product 61236
                slug: product-61236
                meta_title: null
                meta_description: null
                meta_keywords: null
                variant_count: 0
                available_on: null
                purchasable: true
                in_stock: false
                backorderable: true
                available: true
                description: Minima nisi impedit aut sed aspernatur repellendus ullam quisquam. Quod ab vero occaecati quasi. Quasi in tempore iure aut praesentium reprehenderit repellat. Voluptatem fugit eius natus quisquam rerum animi placeat cumque. Pariatur quaerat porro possimus animi at facere eaque. Molestias accusamus neque officiis ut aspernatur totam saepe. Debitis at voluptatibus libero ducimus totam non asperiores reprehenderit. Veritatis eos iusto quis sapiente magnam. Dignissimos inventore quo et ipsam reprehenderit praesentium vitae minima. Inventore eaque praesentium earum ipsam consequatur. Corporis voluptatem iure ipsam iste perferendis quaerat at sit. Nesciunt laudantium itaque necessitatibus possimus provident enim quos. Aperiam a quis aliquam quas necessitatibus eos ut fuga. Quaerat labore nobis animi molestiae. Consequuntur rem molestias distinctio ipsa.
                description_html: 'Minima nisi impedit aut sed aspernatur repellendus ullam quisquam. Quod ab vero occaecati quasi. Quasi in tempore iure aut praesentium reprehenderit repellat. Voluptatem fugit eius natus quisquam rerum animi placeat cumque.

                  Pariatur quaerat porro possimus animi at facere eaque. Molestias accusamus neque officiis ut aspernatur totam saepe. Debitis at voluptatibus libero ducimus totam non asperiores reprehenderit. Veritatis eos iusto quis sapiente magnam.

                  Dignissimos inventore quo et ipsam reprehenderit praesentium vitae minima. Inventore eaque praesentium earum ipsam consequatur. Corporis voluptatem iure ipsam iste perferendis quaerat at sit. Nesciunt laudantium itaque necessitatibus possimus provident enim quos.

                  Aperiam a quis aliquam quas necessitatibus eos ut fuga. Quaerat labore nobis animi molestiae. Consequuntur rem molestias distinctio ipsa.'
                default_variant_id: variant_UkLWZg9DAJ
                thumbnail_url: null
                tags: []
                price:
                  id: price_UkLWZg9DAJ
                  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
                  variant_id: variant_UkLWZg9DAJ
                  created_at: '2026-06-12T17:25:03.263Z'
                  updated_at: '2026-06-12T17:25:03.263Z'
                original_price: null
                status: active
                metadata: {}
                deleted_at: null
                created_at: '2026-06-12T17:25:03.252Z'
                updated_at: '2026-06-12T17:25:03.269Z'
                tax_category_id: taxcat_UkLWZg9DAJ
              schema:
                $ref: '#/components/schemas/Product'
        '404':
          description: product not found
          content:
            application/json:
              example:
                error:
                  code: record_not_found
                  message: Product not found
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    patch:
      summary: Update a product
      tags:
      - Products
      security:
      - api_key: []
        bearer_auth: []
      description: 'Updates a product. Only provided fields are updated.


        **Required scope:** `write_products` (for API-key authentication).'
      x-codeSamples:
      - lang: javascript
        label: Spree Admin SDK
        source: "import { createAdminClient } from '@spree/admin-sdk'\n\nconst client = createAdminClient({\n  baseUrl: 'https://your-store.com',\n  secretKey: 'sk_xxx',\n})\n\nconst product = await client.products.update('prod_86Rf07xd4z', {\n  name: 'Updated Name',\n  status: 'active',\n  tags: ['eco', 'sale'],\n})"
      parameters:
      - name: x-spree-api-key
        in: header
        required: true
        schema:
          type: string
      - name: Authorization
        in: header
        required: true
        description: Bearer token for admin authentication
        schema:
          type: string
      - name: id
        in: path
        required: true
        description: Product ID
        schema:
          type: string
      responses:
        '200':
          description: product updated
          content:
            application/json:
              example:
                id: prod_UkLWZg9DAJ
                name: Updated Name
                slug: product-637715
                meta_title: null
                meta_description: null
                meta_keywords: null
                variant_count: 0
                available_on: null
                purchasable: true
                in_stock: false
                backorderable: true
                available: true
                description: Minima esse id porro impedit aliquid quam sint. Vero exercitationem voluptate consequatur fuga eos dolorum corrupti recusandae. Non similique facere beatae repudiandae exercitationem corrupti facilis suscipit. Impedit distinctio expedita tempora itaque. Omnis quisquam eaque iure alias officia. Consequatur molestiae error nostrum consectetur sint perferendis. Nesciunt fugit dolorem dolorum sed totam nulla occaecati. Qui quas aliquam occaecati harum consequatur ratione temporibus perspiciatis. Eos labore officia commodi quisquam. Odio expedita necessitatibus minus non rem pariatur dignissimos voluptatum. Illum molestiae totam perferendis repudiandae consectetur maxime. Tenetur architecto qui voluptatem culpa sint aspernatur eum voluptates. Suscipit reiciendis eveniet error quae temporibus enim. Atque quia repellat sequi dignissimos nostrum soluta perspiciatis aliquam. Iste quis similique eaque in. Sint voluptatum saepe pariatur aspernatur est nisi odio. Sequi atque porro nihil possimus dolorem eum. Laboriosam consectetur vitae iusto autem tempora doloremque non. Sint rerum esse cumque reprehenderit consequuntur ad non ratione. Earum quo quae reiciendis facere.
                description_html: 'Minima esse id porro impedit aliquid quam sint. Vero exercitationem voluptate consequatur fuga eos dolorum corrupti recusandae. Non similique facere beatae repudiandae exercitationem corrupti facilis suscipit.

                  Impedit distinctio expedita tempora itaque. Omnis quisquam eaque iure alias officia. Consequatur molestiae error nostrum consectetur sint perferendis. Nesciunt fugit dolorem dolorum sed totam nulla occaecati. Qui quas aliquam occaecati harum consequatur ratione temporibus perspiciatis.

                  Eos labore officia commodi quisquam. Odio expedita necessitatibus minus non rem pariatur dignissimos voluptatum. Illum molestiae totam perferendis repudiandae consectetur maxime. Tenetur architecto qui voluptatem culpa sint aspernatur eum voluptates.

                  Suscipit reiciendis eveniet error quae temporibus enim. Atque quia repellat sequi dignissimos nostrum soluta perspiciatis aliquam. Iste quis similique eaque in.

                  Sint voluptatum saepe pariatur aspernatur est nisi odio. Sequi atque porro nihil possimus dolorem eum. Laboriosam consectetur vitae iusto autem tempora doloremque non. Sint rerum esse cumque reprehenderit consequuntur ad non ratione. Earum quo quae reiciendis facere.'
                default_variant_id: variant_UkLWZg9DAJ
                thumbnail_url: null
                tags: []
                price:
                  id: price_UkLWZg9DAJ
                  amount: '19.99'
                  amount_in_cents: 1999
                  compare_at_amount: null
                  compare_at_amount_

# --- truncated at 32 KB (208 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/spree/refs/heads/main/openapi/spree-products-api-openapi.yml