{"openapi":"3.1.0","info":{"title":"CostLens Estimate API","version":"2026.08.18-legacy-calibrated-r2","description":"Versioned, underwriting-grade retrofit cost + incentive estimate API. Wraps the CostLens served engine (calibrated against a corpus of cost records, some synthetic). See https://www.incentedge.com/citylens/methodology for the full methodology writeup.","contact":{"name":"IncentEdge LLC","url":"https://www.incentedge.com"}},"servers":[{"url":"https://www.incentedge.com/api/v1","description":"Production"}],"security":[{"ApiKeyAuth":[]}],"paths":{"/estimate":{"post":{"operationId":"createEstimate","summary":"Produce a costed, incentive-stacked retrofit estimate for a building.","description":"Add ?artifact=true to receive the full underwriting-grade audit artifact instead of the base response.","parameters":[{"name":"artifact","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"When true, returns the AuditArtifact shape (equivalent to POST /estimate/artifact)."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimateRequest"}}}},"responses":{"200":{"description":"Estimate produced.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/EstimateResponse"},{"$ref":"#/components/schemas/AuditArtifact"}]}}}},"400":{"description":"Validation failed (malformed body, or a tiers filter that matched nothing)."},"401":{"description":"Missing or invalid API key."},"403":{"description":"API key lacks the cost:read scope."},"404":{"description":"No building found for the supplied bbl."},"422":{"description":"Building resolved but lacks usable building_area — cannot produce an estimate."},"429":{"description":"Rate limit exceeded."},"502":{"description":"Building lookup (CityIntel) failed."},"503":{"description":"CityIntel is not configured on this server."}}}},"/estimate/artifact":{"post":{"operationId":"createEstimateArtifact","summary":"Produce the full underwriting-grade audit artifact (always artifact:true).","description":"Identical request contract to POST /estimate?artifact=true.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimateRequest"}}}},"responses":{"200":{"description":"Audit artifact produced.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditArtifact"}}}},"400":{"description":"Validation failed."},"401":{"description":"Missing or invalid API key."},"403":{"description":"API key lacks the cost:read scope."},"404":{"description":"No building found for the supplied bbl."},"422":{"description":"Building resolved but lacks usable building_area."},"429":{"description":"Rate limit exceeded."}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Format: ie_live_<32 hex chars> or ie_test_<32 hex chars>. Requires the cost:read scope."}},"schemas":{"EstimateRequest":{"type":"object","description":"Provide exactly one of \"bbl\" or \"building\" — never both, never neither.","properties":{"bbl":{"type":"string","description":"10-digit NYC BBL ([1-5]xxxxxxxxx) or a W-prefixed Westchester parcel id. Resolves building context from CityIntel."},"building":{"type":"object","required":["building_area"],"properties":{"building_area":{"type":"number","minimum":0,"exclusiveMinimum":true,"description":"Gross floor area, square feet."},"year_built":{"type":["integer","null"],"minimum":1800,"maximum":2100},"building_class":{"type":["string","null"],"description":"Either a raw NYC DOF building-class code (e.g. \"C6\") or an already-normalized engine class (\"multifamily\" | \"office\" | \"retail\" | \"industrial\" | \"hotel\" | \"healthcare\" | \"education\"). Unrecognized values normalize to null (fail closed) rather than being guessed."},"num_floors":{"type":["integer","null"],"minimum":1},"site_eui":{"type":["number","null"],"minimum":0,"description":"Site Energy Use Intensity, kBtu/sqft/yr."},"region":{"type":"string","enum":["nyc","westchester"]},"dwelling_units":{"type":"integer","minimum":0},"landmark_status":{"type":"boolean"},"energy_grade":{"type":["string","null"],"maxLength":1,"description":"NYC LL33 A-F energy grade."},"estimated_penalty":{"type":["number","null"],"minimum":0,"description":"Estimated annual LL97 penalty exposure, USD."},"compliance_status":{"type":["string","null"]},"energy_community":{"type":"boolean","description":"DOE/NETL Energy Community designation, for the ITC energy-community adder."},"prevailing_wage":{"type":"boolean"}},"additionalProperties":false},"tiers":{"type":"array","items":{"type":"string","enum":["quick_wins","code_compliant","high_performance","net_zero_ready"]},"description":"Optional subset of tiers to return. Defaults to every tier the engine offers for this building."},"labor_basis":{"type":"string","enum":["prevailing","market"],"description":"Metadata/consistency-warning field only. The served (legacy calibrated) engine does not thread labor_basis into pricing — cost and incentive NUMBERS are identical regardless of this value. When \"market\" is selected, incentives whose headline rate assumes prevailing-wage/apprenticeship compliance surface a disclosure warning in consistency_warnings[]."},"include_financing":{"type":"boolean","description":"When true, \"financing\" is required and each tier response includes ranked financing structures."},"financing":{"type":"object","required":["owner_type","mortgage"],"properties":{"owner_type":{"type":"string","enum":["coop","condo","nonprofit","for_profit","public"]},"mortgage":{"type":"object","required":["exists","holder_class","refi_in_progress"],"properties":{"exists":{"type":"boolean"},"holder_class":{"type":["string","null"],"enum":["bank","cmbs","agency",null]},"refi_in_progress":{"type":"boolean"}}},"scope_cost":{"type":"number","description":"Defaults to the tier's total project cost when omitted."},"all_electric_outcome":{"type":"boolean"},"projected_annual_savings":{"type":"number","description":"Defaults to the tier's totalAnnualSavings when omitted."},"dr_revenue_year1":{"type":"number"},"census_flags":{"type":"object","properties":{"energy_community":{"type":"boolean"}}},"single_commercial_owner":{"type":"boolean"},"combined_energy_water_savings_pct":{"type":"number","minimum":0,"maximum":100},"energy_savings_pct":{"type":"number","minimum":0,"maximum":100},"max_combined_ltc":{"type":"number","minimum":0,"maximum":1},"now":{"type":"string","format":"date-time","description":"Injectable clock for deterministic rate-staleness scoring and artifact reproducibility. Defaults to request time."}},"additionalProperties":false}},"required":[],"additionalProperties":false},"EstimateResponse":{"type":"object","properties":{"methodology_version":{"type":"string"},"data_snapshot":{"type":"object","properties":{"calibration_asof":{"type":"string","format":"date-time"},"escalation_series_last":{"type":"string","format":"date"},"catalog_version":{"type":"string"}}},"measured_accuracy":{"type":"object","description":"MEASURED backtest accuracy from the Phase 4a calibration corpus of cost records (some synthetic). Never a marketing claim.","properties":{"category":{"type":"string"},"mape":{"type":["number","null"]},"bias":{"type":["number","null"],"description":"Mean signed percentage error of the RAW itemized estimate, (expected - actual) / actual. Negative means the bottom-up total runs low against the calibration corpus of cost records (some synthetic). Read live from the calibration artifact."},"bias_correction_applied":{"type":"number","description":"The multiplier applied to produce each tier's sensitivity.calibratedExpected. 1.0 means no correction was applied. Published so `bias` is not double-counted by hand: the correction is already in calibratedExpected."},"n":{"type":"integer"},"coverage":{"type":["number","null"]},"band":{"type":["object","null"]},"calibration_status":{"type":"string"},"aace_class_analogy":{"type":"object"},"disclosure":{"type":"string"}}},"freshness_summary":{"type":"array","items":{"type":"object"}},"labor_basis":{"type":"string","enum":["prevailing","market"]},"consistency_warnings":{"type":"array","items":{"type":"string"}},"resolution":{"type":"object","description":"How the building context was resolved (bbl vs manual) and the normalized building class used.","properties":{"defaults_applied":{"type":"array","items":{"type":"string"},"description":"Human-readable disclosure of every input the engine defaulted because the request omitted it (e.g. \"tiers\" or \"labor_basis\" not provided). Empty when the request supplied every optional input explicitly."}}},"default_tier":{"type":["object","null"]},"tiers":{"type":"array","items":{"type":"object","properties":{"tier":{"type":"string","enum":["quick_wins","code_compliant","high_performance","net_zero_ready"]},"label":{"type":"string"},"description":{"type":"string"},"target":{"type":"string"},"cost_breakdown":{"type":"object"},"incentives":{"type":"array","items":{"type":"object"}},"excluded_incentives":{"type":"array","items":{"type":"object"}},"roi":{"type":"object"},"measures":{"type":"array","items":{"type":"object"}},"sensitivity":{"type":"object","description":"Cost interval for this tier. READ calibratedExpected, NOT expected, when you want the likely outcome: `expected` is the itemized bottom-up total (what the provenance lines reconcile to, and the basis every percentage-of-cost incentive rates against), and the backtest measures it running low. `calibratedExpected` is that total corrected for the measured bias. The two are equal when no calibration applies.","properties":{"bestCase":{"type":"number","description":"expected * the fitted band low multiplier."},"expected":{"type":"number","description":"The itemized bottom-up total. Also the eligible basis for percentage-of-cost incentives."},"calibratedExpected":{"type":"number","description":"expected * measured_accuracy.bias_correction_applied — the bias-corrected expectation. Equals `expected` when the correction is 1.0."},"worstCase":{"type":"number","description":"expected * the fitted band high multiplier."}}},"financing":{"type":["object","null"]}}}},"generated_at":{"type":"string","format":"date-time"}}},"AuditArtifact":{"allOf":[{"$ref":"#/components/schemas/EstimateResponse"},{"type":"object","properties":{"artifact":{"type":"boolean","enum":[true]},"compliance_statement":{"type":"object","properties":{"c1_statement":{"type":"string"},"c2_note":{"type":"string"},"c3_statement":{"type":"string"}}},"provenance":{"type":"object","properties":{"cost_lines":{"type":"array","items":{"type":"object","properties":{"included_in_total":{"type":"boolean","description":"True when this line is counted in the reconciliation.checks[] sum for its tier. False for technology-line decompositions (source_id \"*:tech:*\"), which restate part of a rollup category and are informational only."}}}},"incentive_programs":{"type":"array","items":{"type":"object"}}}},"reconciliation":{"type":"object","description":"Per-tier proof that the included_in_total provenance lines sum to costBreakdown.totalCost within tolerance. A response never carries reconciliation.all_reconciled: false — the server throws a 500 instead of serving a self-inconsistent artifact.","properties":{"tolerance_note":{"type":"string"},"checks":{"type":"array","items":{"type":"object","properties":{"tier":{"type":"string","enum":["quick_wins","code_compliant","high_performance","net_zero_ready"]},"served_total_cost":{"type":"number"},"reconciled_provenance_sum":{"type":"number"},"discrepancy_usd":{"type":"number"},"discrepancy_pct":{"type":"number"},"tolerance_usd":{"type":"number"},"reconciled":{"type":"boolean"},"included_source_ids":{"type":"array","items":{"type":"string"}},"excluded_source_ids":{"type":"array","items":{"type":"string"}},"excluded_reason":{"type":"string"}}}},"all_reconciled":{"type":"boolean"}}},"reproducibility":{"type":"object","properties":{"methodology_version":{"type":"string"},"data_snapshot":{"type":"object"},"input_hash":{"type":"string","description":"SHA-256 hex digest of the canonicalized request input."},"canonical_input":{"type":"object"},"building_input":{"type":"object","description":"The resolved engine building input this artifact was computed from."},"reproducibility_scope":{"type":"string","description":"Discloses that byte-for-byte reproducibility holds for a fixed (methodology_version, calibration snapshot, canonical_input) tuple, but not necessarily across dates once the calibration snapshot (data_snapshot.calibration_asof) advances."}}}}}]}}}}