Spree Commerce Product Catalog API

Products, variants, and option types

OpenAPI Specification

spree-commerce-product-catalog-api-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: Admin Account / Address Product Catalog 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: Product Catalog
  description: Products, variants, and option types
paths:
  /api/v3/admin/option_types:
    get:
      summary: List option types
      tags:
      - Product Catalog
      security:
      - api_key: []
        bearer_auth: []
      description: 'Returns a paginated list of option types.


        **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: optionTypes } = await client.optionTypes.list()"
      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: q[name_cont]
        in: query
        required: false
        description: Filter by name (contains)
        schema:
          type: string
      - name: expand
        in: query
        required: false
        description: Comma-separated associations to expand (e.g., option_values). 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,label,position). id is always included.
        schema:
          type: string
      responses:
        '200':
          description: option types found
          content:
            application/json:
              example:
                data:
                - id: opt_UkLWZg9DAJ
                  name: foo-size-1
                  label: Size
                  position: 1
                  kind: dropdown
                  metadata: {}
                  filterable: true
                  created_at: '2026-05-24T17:37:03.133Z'
                  updated_at: '2026-05-24T17:37:03.133Z'
                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/OptionType'
                  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 an option type
      tags:
      - Product Catalog
      security:
      - api_key: []
        bearer_auth: []
      description: 'Creates a new option type. Supports nested option values.


        Option values can be provided inline and will be created or updated by name.



        **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 optionType = await client.optionTypes.create({\n  name: 'color',\n  presentation: 'Color',\n  option_values: [\n    { name: 'red', presentation: 'Red' },\n    { name: 'navy', presentation: 'Navy' },\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: option type created
          content:
            application/json:
              example:
                id: opt_gbHJdmfrXB
                name: material
                label: Material
                position: 2
                kind: dropdown
                metadata: {}
                filterable: true
                created_at: '2026-05-24T17:37:03.722Z'
                updated_at: '2026-05-24T17:37:03.722Z'
              schema:
                $ref: '#/components/schemas/OptionType'
        '422':
          description: validation error
          content:
            application/json:
              example:
                error:
                  code: validation_error
                  message: Name can't be blank and Presentation can't be blank
                  details:
                    name:
                    - can't be blank
                    presentation:
                    - can't be blank
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  example: color
                label:
                  type: string
                  example: Color
                position:
                  type: integer
                  example: 1
                filterable:
                  type: boolean
                  example: true
                option_values:
                  type: array
                  items:
                    type: object
                    properties:
                      name:
                        type: string
                        example: red
                      label:
                        type: string
                        example: Red
                      position:
                        type: integer
              required:
              - name
              - label
  /api/v3/admin/option_types/{id}:
    get:
      summary: Get an option type
      tags:
      - Product Catalog
      security:
      - api_key: []
        bearer_auth: []
      description: 'Returns a single option type by ID, including its option 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 optionType = await client.optionTypes.get('ot_UkLWZg9DAJ')"
      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: Option type ID
        schema:
          type: string
      - name: expand
        in: query
        required: false
        description: Comma-separated associations to expand (e.g., option_values). 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,label,position). id is always included.
        schema:
          type: string
      responses:
        '200':
          description: option type found
          content:
            application/json:
              example:
                id: opt_UkLWZg9DAJ
                name: foo-size-5
                label: Size
                position: 1
                kind: dropdown
                metadata: {}
                filterable: true
                created_at: '2026-05-24T17:37:04.014Z'
                updated_at: '2026-05-24T17:37:04.014Z'
              schema:
                $ref: '#/components/schemas/OptionType'
        '404':
          description: option type not found
          content:
            application/json:
              example:
                error:
                  code: record_not_found
                  message: Option type not found
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    patch:
      summary: Update an option type
      tags:
      - Product Catalog
      security:
      - api_key: []
        bearer_auth: []
      description: 'Updates an option type. Supports updating nested option values.


        **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 optionType = await client.optionTypes.update('ot_UkLWZg9DAJ', {\n  presentation: 'Updated Presentation',\n  option_values: [\n    { name: 'red', presentation: 'Crimson' },\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
      - name: id
        in: path
        required: true
        description: Option type ID
        schema:
          type: string
      responses:
        '200':
          description: option type updated
          content:
            application/json:
              example:
                id: opt_UkLWZg9DAJ
                name: foo-size-7
                label: Updated Label
                position: 1
                kind: dropdown
                metadata: {}
                filterable: true
                created_at: '2026-05-24T17:37:04.617Z'
                updated_at: '2026-05-24T17:37:04.942Z'
              schema:
                $ref: '#/components/schemas/OptionType'
        '422':
          description: validation error
          content:
            application/json:
              example:
                error:
                  code: validation_error
                  message: Presentation can't be blank
                  details:
                    presentation:
                    - can't be blank
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  example: color
                label:
                  type: string
                  example: Color
                position:
                  type: integer
                  example: 1
                filterable:
                  type: boolean
                  example: true
                option_values:
                  type: array
                  items:
                    type: object
                    properties:
                      id:
                        type: string
                        description: Existing option value ID to update
                      name:
                        type: string
                        example: red
                      label:
                        type: string
                        example: Red
                      position:
                        type: integer
    delete:
      summary: Delete an option type
      tags:
      - Product Catalog
      security:
      - api_key: []
        bearer_auth: []
      description: 'Deletes an option type.


        **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\nawait client.optionTypes.delete('ot_UkLWZg9DAJ')"
      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: Option type ID
        schema:
          type: string
      responses:
        '204':
          description: option type deleted
  /api/v3/admin/products:
    get:
      summary: List products
      tags:
      - Product Catalog
      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 396394
                  slug: product-396394
                  meta_title: null
                  meta_description: null
                  meta_keywords: null
                  variant_count: 0
                  available_on: '2025-05-24T17:37:34.067Z'
                  purchasable: true
                  in_stock: false
                  backorderable: true
                  available: true
                  description: Eaque soluta sit officiis sequi. Deleniti perspiciatis repudiandae ratione quod illum enim. Tenetur tempora similique soluta corporis magni ea itaque dolore. Harum aliquid tempore facilis amet deleniti facere. Nisi ducimus nihil a optio veniam totam. Libero aut deleniti laudantium aliquam reprehenderit. Nam neque assumenda a nisi iusto aliquid perferendis. Quas tenetur non consequatur assumenda. Quos explicabo error culpa aspernatur quod earum cupiditate omnis. Eaque id iste saepe ratione repellendus. Porro cum ducimus eaque occaecati natus cupiditate itaque. Quisquam esse dolore distinctio labore. Minima excepturi fugiat quibusdam voluptatem.
                  description_html: 'Eaque soluta sit officiis sequi. Deleniti perspiciatis repudiandae ratione quod illum enim. Tenetur tempora similique soluta corporis magni ea itaque dolore. Harum aliquid tempore facilis amet deleniti facere.

                    Nisi ducimus nihil a optio veniam totam. Libero aut deleniti laudantium aliquam reprehenderit. Nam neque assumenda a nisi iusto aliquid perferendis. Quas tenetur non consequatur assumenda. Quos explicabo error culpa aspernatur quod earum cupiditate omnis.

                    Eaque id iste saepe ratione repellendus. Porro cum ducimus eaque occaecati natus cupiditate itaque. Quisquam esse dolore distinctio labore. Minima excepturi fugiat quibusdam voluptatem.'
                  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-05-24T17:37:34.092Z'
                    updated_at: '2026-05-24T17:37:34.092Z'
                  original_price: null
                  status: active
                  make_active_at: '2025-05-24T17:37:34.067Z'
                  discontinue_on: null
                  metadata: {}
                  deleted_at: null
                  created_at: '2026-05-24T17:37:34.079Z'
                  updated_at: '2026-05-24T17:37:34.093Z'
                  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:
      - Product Catalog
      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
                make_active_at: null
                discontinue_on: null
                metadata: {}
                deleted_at: null
                created_at: '2026-05-24T17:37:34.756Z'
                updated_at: '2026-05-24T17:37:34.758Z'
                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:
      - Product Catalog
      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 431256
                slug: product-431256
                meta_title: null
                meta_description: null
                meta_keywords: null
                variant_count: 0
                available_on: '2025-05-24T17:37:35.110Z'
                purchasable: true
                in_stock: false
                backorderable: true
                available: true
                description: Nemo quam et hic libero natus qui. Saepe repudiandae eaque autem provident omnis at quia. Porro fugiat voluptatibus vero dolore beatae minus id. Molestias est illo unde quis. Velit quis at voluptatem ut quam mollitia saepe nam. Eligendi laudantium quis aspernatur ea incidunt culpa. Cupiditate sequi reiciendis aspernatur maiores. Tempore blanditiis sint libero odit veniam.
                description_html: 'Nemo quam et hic libero natus qui. Saepe repudiandae eaque autem provident omnis at quia. Porro fugiat voluptatibus vero dolore beatae minus id. Molestias est illo unde quis.

                  Velit quis at voluptatem ut quam mollitia saepe nam. Eligendi laudantium quis aspernatur ea incidunt culpa. Cupiditate sequi reiciendis aspernatur maiores. Tempore blanditiis sint libero odit veniam.'
                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-05-24T17:37:35.137Z'
                  updated_at: '2026-05-24T17:37:35.137Z'
                original_price: null
                status: active
                make_active_at: '2025-05-24T17:37:35.110Z'
                discontinue_on: null
                metadata: {}
                deleted_at: null
                created_at: '2026-05-24T17:37:35.121Z'
                updated_at: '2026-05-24T17:37:35.138Z'
                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:
      - Product Catalog
      security:
      - api_key: []
        bearer_auth: []
      description: 'Updates a product. Only provided fields are updated.


        **Required scope:** `write_products` (for API-key a

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