openapi: 3.0.3

info:
  title: GetCatalogPrices
  version: 1.0.0
  x-scaled-review: true
  description: >-
    The GetCatalogPrices API provides merchants with the most updated international prices of
    their products in different territories operated by Global‑e. These prices can be used for
    marketing needs (for example, in the Google Shopping Feed or in email marketing
    campaigns). The recommended frequency of usage of this API call is 1 call per day, as
    currency rates are updated in the Global-e system once a day. The maximum number of
    currency results (i.e. product count multiplied by requested countries count) cannot
    exceed 10,000.

# Browsing/catalog endpoint (Merchant → Global-e). The documented Request URL reads
# "https://{globale_api_domain}/Browsing/GetCatalogPrices" and is labelled "link to the QA
# environment". Host normalized to https://{globale_api_domain} to match the rest of the
# corpus; the source scheme (http) and QA-environment label are flagged in the review.
servers:
  - url: "https://{globale_api_domain}"
    variables:
      globale_api_domain:
        # Host is published only as a placeholder in the docs; no fixed value exists.
        # Replace once the API team confirms the real host (see review: server host).
        default: globale_api_domain
        description: Global-e API host, supplied to the merchant by Global-e.

tags:
  - name: GetCatalogPrices
    x-page-title: GetCatalogPrices
  - name: "Direction: Merchant → Global-e"
  - name: "Domain: Browsing & Catalog"

paths:
  /Browsing/GetCatalogPrices:
    # FLAG — HTTP method not documented on the page (no "POST"/"GET" verb shown; only the
    # Request URL and method signature "GetCatalogPrices (FullProductCatalogRequest request)").
    # Modeled as POST per house default and because the endpoint carries a JSON request body.
    # Other /Browsing/* specs in this corpus model inputs as query params per a locked browsing
    # convention, but THIS endpoint's docs explicitly document a JSON request body (a nested
    # Countries/Products object + a "Sample Request Body"), so it is modeled as a body. See review.
    post:
      # summary REMOVED — the source has no purpose-statement heading for this operation, only
      # section titles ("GetCatalogPrices API", "GetCatalogPrices Method"). The prior summary
      # "Retrieve updated international catalogue prices for products" was synthesized. See review §2.
      description: >-
        Receives a catalogue conversion request from a merchant and returns the requested list
        of country and currency prices for the catalogue.
      operationId: getCatalogPrices
      tags:
        - GetCatalogPrices
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/FullProductCatalogRequest"
            example:
              Countries:
                - CountryCode: "FR"
                - CountryCode: "DE"
              Products:
                - ProductCode: "565571"
                  OriginalCurrencyCode: "GBP"
                  OriginalSalePrice: 100.0000
                  VATRate: 0.0
                  ProductClassCode: null
                  IsPriceIncludeVAT: null
                - ProductCode: "565571"
                  OriginalCurrencyCode: "GBP"
                  OriginalSalePrice: 20.000
                  VATRate: 20.0
                  ProductClassCode: null
                  IsPriceIncludeVAT: null
      responses:
        # The page documents no HTTP status code; 200 is conventional for the documented
        # success response (see review). The response example is embedded verbatim.
        '200':
          description: >-
            List of SKUs and related prices in the countries that were sent in the request.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FullProductCatalogResponse"
              example:
                Products:
                  - ProductCode: "P1"
                    Countries:
                      - CountryCode: "FR"
                        Currency:
                          CurrencyCode: "EUR"
                          Price: 142.95
                      - CountryCode: "DE"
                        Currency:
                          CurrencyCode: "EUR"
                          Price: 141.95
                  - ProductCode: "P2"
                    Countries:
                      - CountryCode: "FR"
                        Currency:
                          CurrencyCode: "EUR"
                          Price: 23.95
                      - CountryCode: "DE"
                        Currency:
                          CurrencyCode: "EUR"
                          Price: 23.95
        # FLAG — no error status code and no error response shape are documented in the guide.
        # The intro states "If the API call exceeds this number, a failure message is sent back
        # as a response, and no international prices are retrieved" — prose only, no schema.
        # ErrorInfo is the house-standard error model, attached here as a `default` response so
        # no specific status code is invented. See review §2.
        default:
          description: >-
            Failure. The guide states a failure message is sent back when the request exceeds
            the maximum currency-results limit; no error status code or error shape is
            documented (ErrorInfo is the house-standard error model).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorInfo"

components:

  schemas:

    # ---- Request schemas ----------------------------------------------------
    # Field descriptions verbatim from the CatalogProductRequest / FullCatalogCountryRequest
    # parameter tables. Types: String->string, Decimal->number, Boolean->boolean.
    FullProductCatalogRequest:
      type: object
      title: FullProductCatalogRequest
      # Required set resolved 2026-07-19 (Neo code recheck, core/BL/Product/ProductFeedBL.cs +
      # core/API/Controllers/BrowsingController.cs:1472):
      #  - Products IS required — BrowsingController validates a non-empty, non-null Products list
      #    at the API boundary (ValidateListNotEmptyNotNull).
      #  - Countries is NOT required — when omitted/empty, GetMerchantCountriesListRequest
      #    auto-resolves the merchant's IsOperatedByGlobalE countries (ProductFeedBL.cs:691-715).
      #    The source guide's blank Mandatory cell was previously inferred as required; corrected.
      required:
        - Products
      properties:
        Countries:
          type: array
          items:
            $ref: "#/components/schemas/FullCatalogCountryRequest"
          description: >-
            List of countries for the response. Optional — if omitted, prices are returned for all
            countries the merchant is operated in by Global-e, using each country's configured
            price-feed/default currency
        Products:
          type: array
          items:
            $ref: "#/components/schemas/CatalogProductRequest"
          description: >-
            List of product information. Will include the entire catalogue required for the
            response

    FullCatalogCountryRequest:
      type: object
      title: FullCatalogCountryRequest
      # Required confirmed 2026-07-19 (Neo code recheck): when a Countries entry IS supplied,
      # its CountryCode must resolve via CountriesBL.GetCountry or the call throws
      # (ProductFeedBL.cs:770; SetCountryMerchantCurrencies). The Countries array itself is
      # optional (see FullProductCatalogRequest), but CountryCode is required within each entry.
      required:
        - CountryCode
      properties:
        CountryCode:
          type: string
          description: Country code for the requested country

    CatalogProductRequest:
      type: object
      title: CatalogProductRequest
      # Required set resolved 2026-07-19 (Neo code recheck). The DTO is a POCO with no [Required]
      # validation; enforcement is behavioral:
      #  - ProductCode — kept required: it is the product-lookup key (ProductsBL.GetCachedProductsListByCodes)
      #    and is echoed back for identification. NOTE: not API-enforced per item — per-item
      #    ValidateProductCodes is commented out (ProductFeedBL.cs:575), so unresolved codes are
      #    silently dropped rather than rejected; only the Products LIST non-emptiness is enforced.
      #  - OriginalSalePrice — kept required: it is the value being priced; omitting it defaults the
      #    decimal to 0 and yields meaningless 0 prices (not API-enforced).
      #  - VATRate — REMOVED from required: code treats 0/omitted as valid. RemoveMerchantVAT only
      #    strips when VATRate != 0, and the target-country VAT uses a 4-tier fallback
      #    (GetVATRateForProductFeed, ProductFeedBL.cs:601-677) where the caller's VATRate is only
      #    the FINAL fallback. Previously asserted required from the doc's blank cell; corrected.
      required:
        - ProductCode
        - OriginalSalePrice
      properties:
        ProductCode:
          type: string
          description: >-
            ProductCode (SKU) for the product. Returned with the response for product
            identification
        OriginalCurrencyCode:
          type: string
          description: >-
            Currency code for the received product. If left empty, the configured merchant
            currency is assumed
        OriginalSalePrice:
          type: number
          description: Price in original currency
        VATRate:
          # Source type designation is "Deimal" (typo for Decimal); modeled as number. See review.
          type: number
          description: Local VAT rate of the product in the merchant country
        ProductClassCode:
          type: string
          nullable: true
          # Source description contains a copy-paste error (a trailing IsPriceIncludeVAT
          # sentence): "Product class code used by the merchant to overwrite country coefficient
          # rate. If not set, the default is True. Indicates whether the price includes merchant
          # VAT rate". Only the first sentence applies to ProductClassCode; the erroneous
          # trailing text is flagged in the review and omitted here.
          description: >-
            Product class code used by the merchant to overwrite country coefficient rate.
        IsPriceIncludeVAT:
          type: boolean
          nullable: true
          default: true
          description: >-
            If not set, the default is True. Indicates whether the price includes merchant VAT
            rate.

    # ---- Response schemas ---------------------------------------------------
    # Field descriptions verbatim from the CatalogProductResponse / CatalogCountryResponse /
    # CatalogCurrencyResponse parameter tables. No Mandatory markers present.
    FullProductCatalogResponse:
      type: object
      title: FullProductCatalogResponse
      properties:
        Products:
          type: array
          items:
            $ref: "#/components/schemas/CatalogProductResponse"
          description: >-
            List of requested products with a list of prices for each required country

    CatalogProductResponse:
      type: object
      title: CatalogProductResponse
      properties:
        ProductCode:
          type: string
          description: ProductCode (SKU) for the product. Same as the received value in the request
        Countries:
          type: array
          items:
            $ref: "#/components/schemas/CatalogCountryResponse"
          description: List of relevant country results for the product.

    CatalogCountryResponse:
      type: object
      title: CatalogCountryResponse
      properties:
        CountryCode:
          type: string
          description: Country Code of the current returned country
        # Resolved (2026-07-19, Neo code recheck): the source guide's table types "Currency"
        # as "List of CatalogCurrencyResponse", but the code is authoritative — Currency is a
        # SINGLE object. In core/BL/Product/ProductFeedBL.cs (GetCatalogPrices, lines 485-519),
        # CatalogProductResponse.Countries is List<CatalogCountryResponse> (the list level), and
        # each CatalogCountryResponse.Currency is one CatalogCurrencyResponse. Multiple currencies
        # for a country surface as repeated Countries entries, not as an array here. This matches
        # the worked Response example (single object). See review §2 flag A1.
        Currency:
          description: Currency value (code and price) for the current product and country
          allOf:
            - $ref: "#/components/schemas/CatalogCurrencyResponse"

    CatalogCurrencyResponse:
      type: object
      title: CatalogCurrencyResponse
      properties:
        CurrencyCode:
          type: string
          description: Currency Code of the current returned currency
        Price:
          type: number
          description: Price for the specific product in the relevant country and currency

    # ---- Error model (house standard) ---------------------------------------
    ErrorInfo:
      type: object
      title: ErrorInfo
      # House-standard error model. NOT documented for this endpoint (the guide describes
      # failure only as prose). See review §2.
      properties:
        Code:
          type: string
        Error:
          type: string
        Description:
          type: string
