openapi: 3.1.0
info:
  title: Car Appraisal BC Estimate API
  version: 1.0.0
  description: |
    Free car value estimation API for BC vehicles using AutoTrader market data.
    
    Returns asking price ranges (private and dealer) for similar vehicles based on
    current AutoTrader listings. Not an official appraisal — use for market research only.
    
    **Important:**
    - No API key required
    - No Turnstile verification for GET requests
    - Rate-limited per visitor and daily scrape budget
    - Results are AutoTrader asking prices, not sold prices or official CBB values
    - Cannot be used for ICBC claims, tax filings, or legal purposes
    
    **Usage:**
    1. Call GET /estimate with vehicle parameters
    2. If response is status=ready, use the estimate immediately
    3. If response is status=pending, poll with the provided cacheKey every 3 seconds
    
    **More info:**
    - Agent guide: https://carappraisalbc.com/for-agents/
    - Human form: https://carappraisalbc.com/tools/whats-my-car-worth/
    - llms.txt: https://carappraisalbc.com/llms.txt
  contact:
    name: Car Appraisal BC
    url: https://carappraisalbc.com/contact/
  license:
    name: Proprietary
    url: https://carappraisalbc.com/terms/

servers:
  - url: https://car-appraisal-bc-estimate.siftai.workers.dev
    description: Production API

paths:
  /estimate:
    get:
      summary: Get car value estimate
      description: |
        Returns market value estimate based on current AutoTrader listings.
        
        **Cache behavior:**
        - Cache hit: Returns estimate immediately with status=ready
        - Cache miss: Returns status=pending with cacheKey; poll with ?key=CACHEKEY
        
        **Polling:**
        - Poll every 3 seconds with the cacheKey parameter
        - Max wait time: 2 minutes
        - Do NOT invent placeholder values while pending
      operationId: getEstimate
      parameters:
        - name: year
          in: query
          required: true
          schema:
            type: integer
            minimum: 1980
            maximum: 2027
          description: Vehicle model year
          example: 2018
        
        - name: make
          in: query
          required: true
          schema:
            type: string
            minLength: 1
          description: Vehicle manufacturer
          example: Honda
        
        - name: model
          in: query
          required: true
          schema:
            type: string
            minLength: 1
          description: Vehicle model name
          example: Civic
        
        - name: mileageKm
          in: query
          required: true
          schema:
            type: integer
            minimum: 0
            maximum: 800000
          description: Odometer reading in kilometers
          example: 85000
        
        - name: region
          in: query
          required: false
          schema:
            type: string
            default: "Vancouver, BC"
          description: BC city or region for geographic search
          example: "Vancouver, BC"
        
        - name: trim
          in: query
          required: false
          schema:
            type: string
          description: Specific trim level for narrower comps
          example: "EX"
        
        - name: radiusKm
          in: query
          required: false
          schema:
            type: integer
            enum: [10, 20, 50, 100, 150, 200, 250, 300, 400]
            default: 100
          description: Search radius in kilometers
          example: 100
        
        - name: key
          in: query
          required: false
          schema:
            type: string
          description: Cache key for polling pending estimates
          example: "2018-Honda-Civic-Vancouver-100"
      
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/EstimateReady'
                  - $ref: '#/components/schemas/EstimatePending'
                  - $ref: '#/components/schemas/EstimateError'
              examples:
                ready:
                  summary: Cache hit - estimate ready
                  value:
                    status: "ready"
                    cached: true
                    estimate:
                      private:
                        low: 18500
                        mid: 20800
                        high: 23000
                      dealer:
                        low: 19000
                        mid: 21500
                        high: 24000
                      confidence: "high"
                    listings:
                      - price: 18500
                        mileageKm: 92000
                        city: "Vancouver"
                        sellerType: "Private"
                        url: "https://www.autotrader.ca/..."
                      - price: 21000
                        mileageKm: 78000
                        city: "Burnaby"
                        sellerType: "Dealer"
                        url: "https://www.autotrader.ca/..."
                    summary: "Based on 12 AutoTrader listings near Vancouver, BC, your 2018 Honda Civic is estimated at $18,500-$23,000 private, $19,000-$24,000 dealer."
                    caveats:
                      - "These are asking prices, not final sale prices"
                      - "Not an official appraisal"
                      - "Cannot be used for ICBC claims or tax filings"
                    input:
                      year: 2018
                      make: "Honda"
                      model: "Civic"
                      mileageKm: 85000
                      region: "Vancouver, BC"
                      radiusKm: 100
                
                pending:
                  summary: Cache miss - searching listings
                  value:
                    status: "pending"
                    cacheKey: "2018-Honda-Civic-Vancouver-100"
                    message: "Searching AutoTrader listings..."
                
                error:
                  summary: Error response
                  value:
                    status: "error"
                    error: "No listings found for this vehicle in the specified region. Try expanding your search radius."
        
        '400':
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EstimateError'
              example:
                status: "error"
                error: "Missing required parameter: year"
        
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EstimateError'
              example:
                status: "error"
                error: "Rate limit exceeded. Please try again later."

components:
  schemas:
    EstimateReady:
      type: object
      required:
        - status
        - estimate
        - listings
      properties:
        status:
          type: string
          enum: ["ready"]
        cached:
          type: boolean
          description: Whether this result came from cache
        estimate:
          type: object
          required:
            - private
            - dealer
            - confidence
          properties:
            private:
              $ref: '#/components/schemas/PriceRange'
            dealer:
              $ref: '#/components/schemas/PriceRange'
            confidence:
              type: string
              enum: ["high", "medium", "low"]
              description: Confidence level based on listing volume (high=8+, medium=4-7, low=1-3)
        listings:
          type: array
          items:
            $ref: '#/components/schemas/Listing'
        summary:
          type: string
          description: Human-readable market summary
        caveats:
          type: array
          items:
            type: string
          description: Important disclaimers and context
        input:
          type: object
          description: Echo of search parameters
    
    EstimatePending:
      type: object
      required:
        - status
        - cacheKey
      properties:
        status:
          type: string
          enum: ["pending"]
        cacheKey:
          type: string
          description: Use this key to poll for results with ?key=CACHEKEY
        message:
          type: string
          description: Status message
    
    EstimateError:
      type: object
      required:
        - status
        - error
      properties:
        status:
          type: string
          enum: ["error"]
        error:
          type: string
          description: Human-readable error message
    
    PriceRange:
      type: object
      required:
        - low
        - mid
        - high
      properties:
        low:
          type: integer
          description: Low asking price in CAD
        mid:
          type: integer
          description: Median asking price in CAD
        high:
          type: integer
          description: High asking price in CAD
    
    Listing:
      type: object
      properties:
        price:
          type: integer
          description: Asking price in CAD
        mileageKm:
          type: integer
          description: Odometer reading in kilometers
        city:
          type: string
          description: Listing location city
        sellerType:
          type: string
          enum: ["Private", "Dealer"]
          description: Type of seller
        url:
          type: string
          format: uri
          description: Link to AutoTrader listing
