# Auto-generated from TypeScript types
# Do not edit manually - run 'pnpm generate:openapi' instead
# Generated at: 2026-02-21T06:29:16.456Z

openapi: 3.1.0
info:
  title: Bowlly API
  version: 1.0.0
  description: "Bowlly API for cat food product search and comparison. Designed
    for GPT Actions integration to help users find optimal cat food based on
    ingredients and health conditions. Rate limit: 100 requests per minute per
    API key."
servers:
  - url: https://api.bowlly.net
    description: Production API
  - url: https://api-dev.bowlly.net
    description: Development API
paths:
  /agent/products:
    get:
      operationId: searchProducts
      summary: Search cat food products
      description: Search and filter cat food products by ingredients, health
        conditions, and nutritional criteria. Returns products with quality
        scores and nutritional data for ingredient analysis.
      parameters:
        - name: search
          in: query
          description: Search term for product name, brand, or ingredients
          required: false
          schema:
            type: string
          example: grain-free chicken
        - name: form
          in: query
          description: Filter by product form (dry or wet food)
          required: false
          schema:
            type: string
            enum:
              - dry
              - wet
          example: dry
        - name: grainFree
          in: query
          description: Filter by grain-free status
          required: false
          schema:
            type: boolean
        - name: primaryProtein
          in: query
          description: Filter by primary protein type
          required: false
          schema:
            type: string
            enum:
              - chicken
              - fish
              - beef
              - duck
              - lamb
              - turkey
              - mixed
          example: chicken
        - name: minMeatScore
          in: query
          description: Minimum meat quality score (0-100)
          required: false
          schema:
            type: integer
            minimum: 0
            maximum: 100
        - name: maxMeatScore
          in: query
          description: Maximum meat quality score (0-100)
          required: false
          schema:
            type: integer
            minimum: 0
            maximum: 100
        - name: minProtein
          in: query
          description: Minimum protein percentage
          required: false
          schema:
            type: integer
            minimum: 0
            maximum: 100
        - name: maxProtein
          in: query
          description: Maximum protein percentage
          required: false
          schema:
            type: integer
            minimum: 0
            maximum: 100
        - name: conditions
          in: query
          description: Comma-separated condition tags (sensitive, urinary, hairball, diet,
            indoor)
          required: false
          schema:
            type: string
          example: sensitive,urinary
        - name: offset
          in: query
          description: Pagination offset
          required: false
          schema:
            type: integer
            default: 0
            minimum: 0
        - name: limit
          in: query
          description: Number of results to return (max 50)
          required: false
          schema:
            type: integer
            default: 20
            minimum: 1
            maximum: 50
        - name: agent
          in: query
          description: Agent identifier for analytics (e.g., 'chatgpt', 'perplexity')
          required: false
          schema:
            type: string
          example: chatgpt
      responses:
        "200":
          description: Successful response with product list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgentProductResponse"
        "400":
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "429":
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /agent/products/{id}:
    get:
      operationId: getProductDetail
      summary: Get detailed product information
      description: Get detailed information about a specific cat food product
        including complete ingredients, nutritional breakdown, and quality
        metrics.
      parameters:
        - name: id
          in: path
          description: Unique product identifier
          required: true
          schema:
            type: string
        - name: agent
          in: query
          description: Agent identifier for analytics
          required: false
          schema:
            type: string
      responses:
        "200":
          description: Successful response with product details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgentProductDetail"
        "404":
          description: Product not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /agent/products/compare:
    post:
      operationId: compareProducts
      summary: Compare multiple products side-by-side
      description: Compare multiple cat food products side-by-side for nutrition,
        ingredients, and quality. Accepts 2-5 product IDs.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CompareRequest"
      responses:
        "200":
          description: Successful comparison response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompareResponse"
        "400":
          description: Invalid request (too few products or invalid IDs)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
components:
  schemas:
    AgentProduct:
      type: object
      required:
        - id
        - name
        - brand
        - detailUrl
      properties:
        id:
          type: string
          description: Unique product identifier
        name:
          type: string
          description: Product name
        brand:
          type: string
          description: Brand name
        detailUrl:
          type: string
          format: uri
          description: URL to Bowlly product detail page with agent tracking
        imageUrl:
          type: string
          format: uri
          description: Product image URL
        form:
          type: string
          enum:
            - dry
            - wet
          description: Product form type
        lifeStageTags:
          type: array
          items:
            type: string
            enum:
              - kitten
              - adult
              - senior
              - all
          description: Applicable life stages
        conditionTags:
          type: array
          items:
            type: string
            enum:
              - sensitive
              - urinary
              - hairball
              - diet
              - indoor
          description: Health condition tags
        nutrition:
          type: object
          properties:
            protein:
              type: number
              description: Protein percentage (min)
            fat:
              type: number
              description: Fat percentage (min)
            fiber:
              type: number
              description: Fiber percentage (max)
            moisture:
              type: number
              description: Moisture percentage (max)
        derivedMetrics:
          type: object
          properties:
            meatScore:
              type: number
              minimum: 0
              maximum: 100
              description: Meat content quality score (0-100)
            carbEstimated:
              type: number
              description: Estimated carbohydrate percentage
    AgentProductResponse:
      type: object
      required:
        - items
        - meta
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/AgentProduct"
        meta:
          $ref: "#/components/schemas/AgentProductMeta"
    AgentProductMeta:
      type: object
      required:
        - total
        - offset
        - limit
        - hasMore
        - apiVersion
        - timestamp
      properties:
        total:
          type: integer
          description: Total number of matching products
        offset:
          type: integer
          description: Current pagination offset
        limit:
          type: integer
          description: Items per page
        hasMore:
          type: boolean
          description: Whether more results are available
        query:
          type: object
          description: Query parameters used
        executionTimeMs:
          type: integer
          description: Query execution time in milliseconds
        apiVersion:
          type: string
          description: API version
        timestamp:
          type: string
          format: date-time
          description: Response timestamp
    AgentProductDetail:
      allOf:
        - $ref: "#/components/schemas/AgentProduct"
        - type: object
          properties:
            ingredientsNormalized:
              type: array
              items:
                type: string
              description: Normalized ingredient list
            nutrients:
              type: array
              items:
                type: object
              description: Additional nutrient information
    CompareRequest:
      type: object
      required:
        - productIds
      properties:
        productIds:
          type: array
          minItems: 2
          maxItems: 5
          items:
            type: string
          description: Array of product IDs to compare (2-5 products)
        focus:
          type: string
          enum:
            - nutrition
            - ingredients
            - price
            - all
          default: all
          description: Comparison focus area
    CompareResponse:
      type: object
      required:
        - products
        - comparison
      properties:
        products:
          type: array
          items:
            $ref: "#/components/schemas/AgentProduct"
          description: Full product details for each compared item
        comparison:
          type: object
          properties:
            nutrition:
              type: object
              properties:
                highestProtein:
                  $ref: "#/components/schemas/ProductRef"
                lowestCarbs:
                  $ref: "#/components/schemas/ProductRef"
                bestMeatScore:
                  $ref: "#/components/schemas/ProductRef"
            highlights:
              type: array
              items:
                type: string
              description: Key differences and recommendations
    ProductRef:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        value:
          type: number
          description: The metric value
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          description: Error message
        code:
          type: string
          description: Error code (e.g., RATE_LIMITED, NOT_FOUND)
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: API key for authenticating GPT Actions requests
security:
  - ApiKeyAuth: []
