openapi: 3.1.0
info:
  title: CheapBestDeals Shopping API
  version: 1.0.0
  description: >-
    Read-only shopping API for AI assistants. Use affiliateUrl as the outbound purchase link. Do not construct
    marketplace links manually.
  termsOfService: 'https://cheapbestdeals.com/en/terms'
  contact:
    name: CheapBestDeals
    url: 'https://cheapbestdeals.com/en/privacy'
servers:
  - url: 'https://cheapbestdeals.com'
    description: CheapBestDeals production or configured environment
paths:
  /api/marketplaces:
    get:
      operationId: getMarketplaces
      summary: List supported marketplaces
      description: Returns marketplace IDs accepted by the product search and detail endpoints.
      responses:
        '200':
          description: Supported marketplaces
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Marketplace'
  /api/products:
    get:
      operationId: searchProducts
      summary: Search products and deals
      description: Search Amazon products. Product results include affiliateUrl; use that field for outbound purchase links.
      parameters:
        - name: q
          in: query
          required: true
          description: 'Product search query, for example "refrigerator" or Arabic product terms.'
          schema:
            type: string
            minLength: 1
            maxLength: 200
        - name: marketplace
          in: query
          required: false
          description: Marketplace ID. Defaults to Amazon Egypt.
          schema:
            type: string
            enum:
              - www.amazon.eg
              - www.amazon.com
            default: www.amazon.eg
        - name: category
          in: query
          required: false
          description: Optional Amazon category/search index.
          schema:
            type: string
        - name: limit
          in: query
          required: false
          description: Maximum number of products to return.
          schema:
            type: integer
            minimum: 1
            maximum: 25
            default: 10
        - name: lang
          in: query
          required: false
          description: Language for AI deal summaries.
          schema:
            type: string
            enum:
              - en
              - ar
            default: en
      responses:
        '200':
          description: Product search results
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProductSearchResponse'
        '400':
          description: Invalid query or marketplace
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  '/api/products/{asin}':
    get:
      operationId: getProductDetails
      summary: Get product details
      description: Fetch one Amazon product by ASIN. Use product.affiliateUrl as the outbound purchase link.
      parameters:
        - name: asin
          in: path
          required: true
          description: Amazon ASIN.
          schema:
            type: string
            minLength: 4
            maxLength: 32
        - name: marketplace
          in: query
          required: false
          description: Marketplace ID. Defaults to Amazon Egypt.
          schema:
            type: string
            enum:
              - www.amazon.eg
              - www.amazon.com
            default: www.amazon.eg
        - name: lang
          in: query
          required: false
          description: Language for AI deal summary.
          schema:
            type: string
            enum:
              - en
              - ar
            default: en
      responses:
        '200':
          description: Product details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProductDetailResponse'
        '404':
          description: Product not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  '/api/products/{asin}/history':
    get:
      operationId: getPriceHistory
      summary: Get product price history
      description: >-
        Returns stored price history for an ASIN and marketplace. History may be empty until the product has been
        observed.
      parameters:
        - name: asin
          in: path
          required: true
          description: Amazon ASIN.
          schema:
            type: string
            minLength: 4
            maxLength: 32
        - name: marketplace
          in: query
          required: false
          description: Marketplace ID. Prefer this over marketplace_id for GPT Actions.
          schema:
            type: string
            enum:
              - www.amazon.eg
              - www.amazon.com
            default: www.amazon.eg
      responses:
        '200':
          description: Price history points
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PriceHistoryPoint'
components:
  schemas:
    Marketplace:
      type: object
      properties:
        id:
          type: string
          description: Marketplace ID accepted by API calls.
        slug:
          type: string
        name:
          type: string
        flag:
          type: string
        currency:
          type: string
        country:
          type: string
        returnPolicyUrl:
          type: string
          format: uri
      required:
        - id
        - slug
        - name
        - currency
    Product:
      type: object
      properties:
        asin:
          type: string
        title:
          type:
            - string
            - 'null'
        description:
          type:
            - string
            - 'null'
        price:
          type:
            - number
            - 'null'
        currency:
          type:
            - string
            - 'null'
        originalPrice:
          type:
            - number
            - 'null'
        originalCurrency:
          type:
            - string
            - 'null'
        rating:
          type:
            - number
            - 'null'
        reviewCount:
          type:
            - number
            - 'null'
        brand:
          type:
            - string
            - 'null'
        imageUrl:
          type:
            - string
            - 'null'
          format: uri
        productUrl:
          type:
            - string
            - 'null'
          format: uri
        affiliateUrl:
          type:
            - string
            - 'null'
          format: uri
          description: Server-generated affiliate purchase link. Use this for outbound shopping links.
        dealDetails:
          type:
            - object
            - 'null'
        offerType:
          type:
            - string
            - 'null'
        dealSummary:
          type:
            - string
            - 'null'
        promoted:
          type: boolean
        merchantName:
          type:
            - string
            - 'null'
        priceTracking:
          $ref: '#/components/schemas/PriceTrackingSummary'
          description: Tracked price history stats from the CheapBestDeals database.
      required:
        - asin
        - affiliateUrl
    PriceTrackingSummary:
      type: object
      description: >-
        Tracked price metrics based on prices observed by CheapBestDeals. All-time low/high means all-time within the
        CheapBestDeals tracking database.
      properties:
        hasTrackedHistory:
          type: boolean
        currentPrice:
          type:
            - number
            - 'null'
        currency:
          type:
            - string
            - 'null'
        trackedAllTimeLow:
          type:
            - number
            - 'null'
          description: Lowest price observed in the CheapBestDeals tracking database.
        trackedAllTimeHigh:
          type:
            - number
            - 'null'
          description: Highest price observed in the CheapBestDeals tracking database.
        trackedAveragePrice:
          type:
            - number
            - 'null'
        trackedDays:
          type: integer
        trackedFirstSeen:
          type:
            - string
            - 'null'
          format: date-time
        trackedLastSeen:
          type:
            - string
            - 'null'
          format: date-time
        isCurrentTrackedAllTimeLow:
          type:
            - boolean
            - 'null'
        isCurrentTrackedAllTimeHigh:
          type:
            - boolean
            - 'null'
        percentAboveTrackedAllTimeLow:
          type:
            - number
            - 'null'
        percentBelowTrackedAllTimeHigh:
          type:
            - number
            - 'null'
      required:
        - hasTrackedHistory
        - currentPrice
        - trackedAllTimeLow
        - trackedAllTimeHigh
        - trackedDays
    ProductSearchResponse:
      type: object
      properties:
        results:
          type: array
          items:
            $ref: '#/components/schemas/Product'
        total:
          type: integer
        marketplace:
          type: string
        query:
          type: string
      required:
        - results
        - total
        - marketplace
        - query
    ProductDetailResponse:
      type: object
      properties:
        product:
          $ref: '#/components/schemas/Product'
      required:
        - product
    PriceHistoryPoint:
      type: object
      properties:
        date:
          type: string
          format: date-time
        price:
          type: number
        original_price:
          type:
            - number
            - 'null'
        available:
          type: boolean
      required:
        - date
        - price
        - available
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
      required:
        - error
