openapi: 3.0.3
info:
  title: Gnowise Unified Valuation API
  version: "3.8"
  description: Enterprise contract for the working Gnowise Unified API endpoint only. Legacy forecast/off-market client pages and the broken interactive OpenAPI client is not included. The docs page includes a simple live tester that lets users paste their own API key and edit the three supported default payloads.
servers:
  - url: https://api.gnowise.com
security:
  - ApiKeyAuth: []
paths:
  /:
    post:
      operationId: unifiedValuation
      summary: Retrieve valuation, rent, rent comparables, FSA-level HPI/neighborhood medians, forecast, risk, liquidity and HPI-adjusted outputs from the Unified API.
      description: Use one of the documented request profiles. Field casing is case-sensitive.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/AddressOnlyRequest'
                - $ref: '#/components/schemas/EnrichedAttributesRequest'
                - $ref: '#/components/schemas/HpiAdjustedRequest'
            examples:
              addressOnly:
                summary: 1. Address-only / minimum detached test
                value:
                  Address: "299 chaplin cres toronto m5p1b1"
                  AptNum: ""
                  PropertyType: "Detached"
                  IsCondo: false
              addressAttributes:
                summary: 2. Address + property attributes
                value:
                  address: "299 chaplin cres"
                  attributes:
                    City: "Toronto"
                    PostalCode: "m5p1b1"
                    NumBedrooms: "3"
                    NumDens: "1"
                    NumBathrooms: "2"
                    NumParkingSpaces: "16"
                    Pool: "Inground"
                    BasementType: "Finished"
                    NumKitchens: "2"
                    PropertyType: "Detached"
                    BuildingStyle: "3-Storey"
                    RoomsArea: "1600"
                    LotArea: "3300"
                    Age: "51-99"
                    AirConditioning: "Central Air"
                    Sqft: null
                  aptNum: ""
                  isCondo: false
                  condition: 3
              historicalHpiAdjusted:
                summary: 3. Historical / HPI-adjusted valuation
                value:
                  Address: "299 chaplin cres toronto m5p1b1"
                  AptNum: ""
                  PropertyType: "Detached"
                  IsCondo: false
                  HistValue: 1500000
                  HistValueDate: "2021-06-15"
                  HistPropertyType: "Detached"
      responses:
        '200':
          description: Successful response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnifiedValuationResponse'
              examples:
                standard:
                  summary: Standard unified response
                  value:
                    Report:
                      gnowise_value: 1883000
                      value_low: 1750000
                      value_high: 2025000
                      valuation_source: "A"
                      valuation_confidence: 0.91
                      gnowise_lease: 4400
                      lease_low: 4100
                      lease_high: 4700
                      lease_confidence: 0.88
                      gnowise_cap_rate: 0.028
                      liquidity_score: 0.68
                      risk_of_decline: 32
                      one_year_growth_rate: -0.04
                      two_year_growth_rate: 0.02
                      price_in_one_year: 1808000
                      price_in_two_years: 1920000
                      property_attributes: {}
                      appr_attributes: {}
                      hpi:
                        M5P_All_median_ci_width: null
                        M5P_Apartment_median_ci_width: 393562.0
                        M5P_Detached_median_ci_width: null
                        M5P_Row_median_ci_width: null
                        M5P_All_median_price: 690725.0
                        M5P_Row_median_price: null
                        M5P_Apartment_median_price: 1216046.0
                        M5P_Detached_median_price: null
                      rent_comps: []
                      request_id: req_01JABCXYZ
        '400':
          description: Bad request. Malformed JSON, missing required field, missing postal code, wrong casing, or invalid field value.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized. Missing or invalid x-api-key.
        '404':
          description: Address not matched or insufficient supported data for a response.
        '429':
          description: Rate limit exceeded. Retry after the Retry-After header if provided and use exponential backoff.
        '500':
          description: Transient server error. Retry with exponential backoff.
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
  schemas:
    AddressOnlyRequest:
      type: object
      additionalProperties: true
      required: [Address, AptNum, PropertyType, IsCondo]
      properties:
        Address:
          type: string
          description: Full address string including city and postal code. Postal code is required.
          example: "299 chaplin cres toronto m5p1b1"
        AptNum:
          type: string
          example: ""
        PropertyType:
          type: string
          example: Detached
        IsCondo:
          type: boolean
          example: false
    HpiAdjustedRequest:
      allOf:
        - $ref: '#/components/schemas/AddressOnlyRequest'
        - type: object
          required: [HistValue, HistValueDate]
          properties:
            HistValue:
              type: number
              description: Historical value in CAD.
              example: 1500000
            HistValueDate:
              type: string
              format: date
              example: "2021-06-15"
            HistPropertyType:
              type: string
              example: Detached
    EnrichedAttributesRequest:
      type: object
      additionalProperties: true
      required: [address, attributes, aptNum, isCondo, condition]
      properties:
        address:
          type: string
          description: Street address string. Postal code is required in attributes.PostalCode for this profile.
          example: "299 chaplin cres"
        attributes:
          type: object
          additionalProperties: true
          required: [PostalCode]
          properties:
            City: { type: string, example: Toronto }
            PostalCode: { type: string, example: m5p1b1 }
            NumBedrooms: { oneOf: [{type: string}, {type: number}], example: "3" }
            NumDens: { oneOf: [{type: string}, {type: number}], example: "1" }
            NumBathrooms: { oneOf: [{type: string}, {type: number}], example: "2" }
            NumParkingSpaces: { oneOf: [{type: string}, {type: number}], example: "16" }
            Pool: { type: string, example: Inground }
            BasementType: { type: string, example: Finished }
            NumKitchens: { oneOf: [{type: string}, {type: number}], example: "2" }
            PropertyType: { type: string, example: Detached }
            BuildingStyle: { type: string, example: 3-Storey }
            RoomsArea: { oneOf: [{type: string}, {type: number}], example: "1600" }
            LotArea: { oneOf: [{type: string}, {type: number}], example: "3300" }
            Age: { type: string, example: 51-99 }
            AirConditioning: { type: string, example: Central Air }
            Sqft: { nullable: true, oneOf: [{type: string}, {type: number}] }
        aptNum:
          type: string
          example: ""
        isCondo:
          type: boolean
          example: false
        condition:
          type: integer
          minimum: 1
          maximum: 5
          example: 3
    UnifiedValuationResponse:
      type: object
      properties:
        Report:
          type: object
          additionalProperties: true
          properties:
            gnowise_value: { type: number, nullable: true }
            value_low: { type: number, nullable: true }
            value_high: { type: number, nullable: true }
            valuation_source: { type: string, enum: [A, H, HA], nullable: true }
            valuation_confidence: { type: number, minimum: 0, maximum: 1, nullable: true }
            gnowise_lease: { type: number, nullable: true }
            lease_low: { type: number, nullable: true }
            lease_high: { type: number, nullable: true }
            lease_confidence: { type: number, minimum: 0, maximum: 1, nullable: true }
            gnowise_cap_rate: { type: number, nullable: true }
            liquidity_score: { type: number, nullable: true }
            risk_of_decline: { type: number, nullable: true }
            one_year_growth_rate: { type: number, nullable: true }
            two_year_growth_rate: { type: number, nullable: true }
            price_in_one_year: { type: number, nullable: true }
            price_in_two_years: { type: number, nullable: true }
            property_attributes: { type: object, nullable: true, additionalProperties: true }
            appr_attributes: { type: object, nullable: true, additionalProperties: true }
            hpi:
              type: object
              nullable: true
              additionalProperties:
                nullable: true
                oneOf:
                  - type: number
                  - type: string
              description: FSA-level neighborhood median price and median CI width fields. Keys commonly follow {FSA}_{Segment}_median_price and {FSA}_{Segment}_median_ci_width.
              example:
                M5P_All_median_ci_width: null
                M5P_Apartment_median_ci_width: 393562.0
                M5P_Detached_median_ci_width: null
                M5P_Row_median_ci_width: null
                M5P_All_median_price: 690725.0
                M5P_Row_median_price: null
                M5P_Apartment_median_price: 1216046.0
                M5P_Detached_median_price: null
            rent_comps:
              nullable: true
              oneOf:
                - type: array
                  items: { type: object, additionalProperties: true }
                - type: object
                  additionalProperties: true
              description: Rent comparable evidence when enabled and available. Preserve returned fields because comparable record shape may vary by configuration.
            request_id: { type: string, nullable: true }
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code: { type: integer }
            type: { type: string }
            message: { type: string }
            details:
              type: array
              items: { type: object, additionalProperties: true }
            request_id: { type: string }
