{
  "openapi": "3.1.0",
  "info": {
    "title": "HeatPumps.co Agent Quote API",
    "version": "1.0",
    "description": "Discover services and locations, validate with dry-run, and submit consented heat pumps quote requests."
  },
  "servers": [
    {
      "url": "https://heat-pumps.co"
    }
  ],
  "paths": {
    "/api/v1/services": {
      "get": {
        "operationId": "listServices",
        "responses": {
          "200": {
            "description": "Supported services"
          }
        }
      }
    },
    "/api/v1/locations": {
      "get": {
        "operationId": "listLocations",
        "responses": {
          "200": {
            "description": "Supported locations"
          }
        }
      }
    },
    "/api/v1/health": {
      "get": {
        "operationId": "healthCheck",
        "responses": {
          "200": {
            "description": "Healthy"
          }
        }
      }
    },
    "/api/v1/products/search": {
      "get": {
        "operationId": "searchHeatPumpCatalog",
        "summary": "Search structured heat-pump product data",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Brand, model, or AHRI text",
              "maxLength": 80
            }
          },
          {
            "name": "ahri",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Exact AHRI certificate number",
              "maxLength": 40
            }
          },
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Exact manufacturer name",
              "maxLength": 80
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Heat-pump form factor",
              "enum": [
                "air-source",
                "mini-split",
                "ducted",
                "geothermal"
              ]
            }
          },
          {
            "name": "min_seer2",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "description": "Minimum SEER2 efficiency",
              "minimum": 0,
              "maximum": 50
            }
          },
          {
            "name": "max_seer2",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "description": "Maximum SEER2 efficiency",
              "minimum": 0,
              "maximum": 50
            }
          },
          {
            "name": "min_hspf2",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "description": "Minimum HSPF2 efficiency",
              "minimum": 0,
              "maximum": 30
            }
          },
          {
            "name": "max_hspf2",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "description": "Maximum HSPF2 efficiency",
              "minimum": 0,
              "maximum": 30
            }
          },
          {
            "name": "min_cop_5",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "description": "Minimum coefficient of performance at 5°F",
              "minimum": 0,
              "maximum": 10
            }
          },
          {
            "name": "max_cop_5",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "description": "Maximum coefficient of performance at 5°F",
              "minimum": 0,
              "maximum": 10
            }
          },
          {
            "name": "min_heating_capacity_5_btu",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "description": "Minimum heating capacity at 5°F in BTU/h",
              "minimum": 0,
              "maximum": 1000000
            }
          },
          {
            "name": "max_heating_capacity_5_btu",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "description": "Maximum heating capacity at 5°F in BTU/h",
              "minimum": 0,
              "maximum": 1000000
            }
          },
          {
            "name": "min_heating_capacity_47_btu",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "description": "Minimum heating capacity at 47°F in BTU/h",
              "minimum": 0,
              "maximum": 1000000
            }
          },
          {
            "name": "max_heating_capacity_47_btu",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "description": "Maximum heating capacity at 47°F in BTU/h",
              "minimum": 0,
              "maximum": 1000000
            }
          },
          {
            "name": "min_nominal_tonnage",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "description": "Minimum nominal system tonnage",
              "minimum": 0,
              "maximum": 100
            }
          },
          {
            "name": "max_nominal_tonnage",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "description": "Maximum nominal system tonnage",
              "minimum": 0,
              "maximum": 100
            }
          },
          {
            "name": "cold_climate",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Require or exclude cold-climate performance (COP at 5°F >= 1.75 and HSPF2 >= 9)"
            }
          },
          {
            "name": "grant_eligible",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Require or exclude products eligible for at least one catalogued Canadian grant program"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Catalog result ordering",
              "enum": [
                "brand",
                "seer2-desc",
                "hspf2-desc",
                "cop-5-desc",
                "heating-capacity-5-desc",
                "tonnage-asc"
              ],
              "default": "brand"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 10
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 5000,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching catalog products",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogSearchResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid search parameters"
          },
          "502": {
            "description": "Catalog service unavailable"
          }
        }
      }
    },
    "/api/v1/quotes": {
      "post": {
        "operationId": "submitQuoteRequest",
        "summary": "Submit a heat pumps quote request",
        "description": "Obtain explicit user consent before submitting PII. Use dry_run=true to validate and preview without creating a lead.",
        "parameters": [
          {
            "name": "dry_run",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QuoteRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dry-run preview"
          },
          "201": {
            "description": "Quote created"
          },
          "400": {
            "description": "Validation error"
          },
          "429": {
            "description": "Rate limited"
          },
          "502": {
            "description": "Persistence adapter failed"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "QuoteRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "consent",
          "name",
          "email",
          "address",
          "city",
          "state",
          "zip",
          "country",
          "service_type",
          "urgency"
        ],
        "properties": {
          "consent": {
            "type": "boolean",
            "description": "Explicit consent to share PII for contractor matching",
            "const": true
          },
          "name": {
            "type": "string",
            "description": "Full name",
            "minLength": 2,
            "maxLength": 120
          },
          "email": {
            "type": "string",
            "description": "Email address",
            "format": "email",
            "maxLength": 254
          },
          "phone": {
            "type": "string",
            "description": "Phone number",
            "minLength": 7,
            "maxLength": 40
          },
          "address": {
            "type": "string",
            "description": "Property street address",
            "minLength": 5,
            "maxLength": 200
          },
          "city": {
            "type": "string",
            "description": "Property city",
            "minLength": 2,
            "maxLength": 80
          },
          "state": {
            "type": "string",
            "description": "US state code",
            "enum": [
              "AL",
              "AK",
              "AZ",
              "AR",
              "CA",
              "CO",
              "CT",
              "DE",
              "FL",
              "GA",
              "HI",
              "ID",
              "IL",
              "IN",
              "IA",
              "KS",
              "KY",
              "LA",
              "ME",
              "MD",
              "MA",
              "MI",
              "MN",
              "MS",
              "MO",
              "MT",
              "NE",
              "NV",
              "NH",
              "NJ",
              "NM",
              "NY",
              "NC",
              "ND",
              "OH",
              "OK",
              "OR",
              "PA",
              "RI",
              "SC",
              "SD",
              "TN",
              "TX",
              "UT",
              "VT",
              "VA",
              "WA",
              "WV",
              "WI",
              "WY",
              "DC"
            ],
            "minLength": 2,
            "maxLength": 2
          },
          "zip": {
            "type": "string",
            "description": "US ZIP code",
            "pattern": "^\\d{5}(?:-\\d{4})?$"
          },
          "country": {
            "type": "string",
            "description": "Country code",
            "const": "US",
            "default": "US"
          },
          "details": {
            "type": "string",
            "description": "Project details",
            "maxLength": 4000
          },
          "agent_source": {
            "type": "string",
            "description": "Submitting agent, e.g. chatgpt",
            "maxLength": 64,
            "default": "agent"
          },
          "agent_version": {
            "type": "string",
            "description": "Optional submitting agent version",
            "maxLength": 64
          },
          "submission_method": {
            "type": "string",
            "description": "openapi, mcp, webmcp, or agent-skill",
            "enum": [
              "openapi",
              "mcp",
              "webmcp",
              "agent-skill"
            ],
            "default": "openapi"
          },
          "website": {
            "type": "string",
            "description": "Spam honeypot; leave empty"
          },
          "service_type": {
            "type": "string",
            "description": "Heat-pump service",
            "enum": [
              "air_source",
              "mini_split",
              "ducted",
              "geothermal",
              "commercial",
              "repair"
            ]
          },
          "home_size": {
            "type": "string",
            "description": "Approximate home size in square feet",
            "maxLength": 20
          },
          "urgency": {
            "type": "string",
            "description": "Requested timing",
            "enum": [
              "emergency",
              "soon",
              "week",
              "flexible"
            ]
          }
        }
      },
      "CatalogSearchResponse": {
        "type": "object",
        "required": [
          "query",
          "pagination",
          "results",
          "human_url"
        ],
        "properties": {
          "query": {
            "type": "object",
            "additionalProperties": true
          },
          "pagination": {
            "type": "object",
            "required": [
              "limit",
              "offset",
              "total",
              "next_offset"
            ],
            "properties": {
              "limit": {
                "type": "integer"
              },
              "offset": {
                "type": "integer"
              },
              "total": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "next_offset": {
                "type": [
                  "integer",
                  "null"
                ]
              }
            }
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "ahri_number",
                "brand",
                "performance",
                "classification",
                "eligibility"
              ],
              "properties": {
                "ahri_number": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "brand": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "outdoor_model": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "indoor_model": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "performance": {
                  "type": "object",
                  "additionalProperties": {
                    "type": [
                      "number",
                      "null"
                    ]
                  }
                },
                "classification": {
                  "type": "object",
                  "additionalProperties": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "eligibility": {
                  "type": "object",
                  "additionalProperties": {
                    "type": [
                      "boolean",
                      "null"
                    ]
                  }
                },
                "match_status": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "data_sources": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            }
          },
          "human_url": {
            "type": "string",
            "format": "uri"
          }
        }
      }
    }
  }
}
