PLUMB  /  FOR INTEGRATORS

Plumb ingest spec.

Versioned JSON contract for structured subject, comparable-grid, and valuation data. Plumb maps it deterministically to UAD 3.6 MISMO XML, PDF, and an Appendix H-1 report that states exactly how many rules were evaluated.

Version 1.0 Status Public, importer-agnostic Last verified 2026-09-06
Check the output Plumb Bob checks your XML against the rules it evaluates and reports the exact count before you submit. Free while it's in beta — start now with code WELCOME2026. Why wait?

This spec describes the JSON shape a comp importer sends to Plumb Bob to produce XSD-validated UAD 3.6 MISMO XML plus an Appendix H-1 compliance report. It is the contract between data-IN (your importer — TrueTracts, DataMaster, or any equivalent MLS/comp export) and UAD-XML-OUT (Plumb's UAD 3.6 builder and published-rule engine).

Plumb's conversational capture flow is SFR-first today. This ingest format is the structured path for comp importers who already hold the facts in rows and want Plumb to emit the XML and compliance report without re-typing. The format is exercised end-to-end by 13 fixture archetypes in the Plumb repo: SFR, condo, 2–4 unit, new-construction, ADU, basement/waterfront, HOA, and refinance.

What Plumb returns

  1. UAD 3.6 MISMO XML — XSD-validated against the official GSE_UAD_3.6.0_v1.3 schema.
  2. Appendix H-1 compliance report — sourced from the published ruleset (v1.5, 2026-08-13): 508 Fatal rules that get a UCDP submission rejected outright, plus 120 Warning/Informational rules. The report states exactly how many rules Plumb evaluated. Each finding's rule ID, severity, and message is traceable to the GSE workbook.
  3. PDF — the redesigned URAR layout (Appendix C-1), rendered from the same model that produced the XML.

The ingest shape

One JSON object, three required blocks: subject, comparables, and valuation. Optional blocks cover site, structure, amenities, defects, and 2–4 unit / income-approach data. The public ingest contract is schemas/plumb_ingest_v1.schema.json, dumped from src/plumb/importer/models.py::PlumbIngestV1. Validate your payload against it. The field names below are ingest keys; docs/plumb_ingest_v1.md carries the field-to-UAD-UID mapping. The internal subject_property/comparable/appraisal.schema.json files describe the emitted model your payload maps onto, which is a separate downstream layer.

{
  "subject_address": "4218 E Mountain View Dr, Mesa, AZ 85215",
  "geocode": {
    "matched_address": "...",
    "latitude": 33.47,
    "longitude": -111.71,
    "state_code": "AZ",
    "county_name": "Maricopa",
    "county_geoid": "04013",
    "census_tract": "04013421102"
  },
  "appraiser_profile": {
    "first_name": "...",
    "last_name": "...",
    "license_number": "...",
    "license_state": "AZ",
    "license_type": "Certified Residential",
    "company_name": "...",
    "email": "...",
    "phone": "...",
    "designations": []
  },
  "lender_client": {
    "lender_name": "...",
    "lender_city": "...",
    "lender_state": "AZ",
    "lender_postal_code": "85003",
    "loan_purpose": "Purchase"
  },
  "characteristics": {
    "bedroom_count": 3,
    "full_bathroom_count": 2,
    "half_bathroom_count": 0,
    "gla_square_feet": 2485,
    "year_built": 1998,
    "overall_condition": "C4",
    "overall_quality": "Q4",
    "market_boundaries": "North: ...; South: ..."
  },
  "physical_structure": {
    "heating_system_type": "ForcedAir",
    "heating_fuel_type": "NaturalGas",
    "cooling_system_type": "Central",
    "foundation_type": "Slab",
    "roof_material_type": "AsphaltShingle",
    "exterior_wall_predominant": "Stucco",
    "stories_above_grade": 1,
    "level_glas": []
  },
  "amenities": {
    "pool_present": false,
    "garage_type": "Attached",
    "garage_spaces": 2
  },
  "defects": [],
  "comparables": [
    {
      "ordinal": 1,
      "address_line": "...",
      "city": "...",
      "state_code": "AZ",
      "postal_code": "85215",
      "sale_price": 642000,
      "sale_date": "2026-04-01",
      "gla_square_feet": 2400,
      "bedroom_count": 3,
      "full_bathroom_count": 2,
      "half_bathroom_count": 0,
      "overall_condition": "C4",
      "overall_quality": "Q4",
      "heating_type": "ForcedAir"
    }
  ],
  "valuation": {
    "appraised_value": 632000,
    "effective_date": "2026-05-25",
    "reconciliation_summary": "...",
    "valuation_conditional_conclusion_type": "AsIs",
    "exposure_time_low_range_days": 21,
    "exposure_time_high_range_days": 60
  }
}

Subject block

FieldTypeNotes
subject_addressstringOne-line street, city, state, ZIP
geocodeobjectCensus geocode; Plumb uses state and postal code for the market rate profile
appraiser_profileobjectName, license, company, contact, designations
lender_clientobjectLender name/address and loan_purpose (Purchase/Refinance)
characteristicsobjectBeds, baths, GLA, year built, condition (C1–C6), quality (Q1–Q6), market boundaries
physical_structureobjectHeating, cooling, foundation, roof, exterior wall, stories
amenitiesobjectPool, garage type/spaces
defectsarrayEach item: description, location, type, category, severity, affects_value, requires_repair

Comparable grid

One entry per comparable. ordinal is 1-indexed and sets grid order.

FieldTypeNotes
ordinalint1-indexed grid position
address_line, city, state_code, postal_codestringComparable address
sale_priceintClosed sale price
sale_datestring (ISO)Closed sale date
gla_square_feetintAbove-grade finished area
bedroom_count, full_bathroom_count, half_bathroom_countint
overall_condition, overall_qualitystringC1–C6, Q1–Q6
heating_typestringOptional; omitted stays omitted (honest gaps)
valuation_use_typestringOptional: SalesComparable (default), GrossRentMultiplierComparable, RentalComparable, PropertyAnalyzedNotUsed

Valuation block

FieldTypeNotes
appraised_valueintFinal reconciled opinion
effective_datestring (ISO)Appraisal effective date
reconciliation_summarystringAppraiser narrative (max 5000 chars)
valuation_conditional_conclusion_typestringAsIs / SubjectToCompletionPerPlans / SubjectToInspection / SubjectToRepair
exposure_time_low_range_days, exposure_time_high_range_daysintMarketing/exposure range
income_approachobject (optional)2–4 unit only: gross_rent_multiplier_factor_number, value_indicated_by_income_approach_amount, income_analysis_comment_description

2–4 unit extension

For 2–4 unit properties, add units (per-unit rent schedule) and rental_summary (aggregate monthly rents) under characteristics:

"units": [
  {
    "bedroom_count": 2,
    "full_bathroom_count": 1,
    "floor_identifier": "1",
    "unit_occupancy_type": "Tenant",
    "unit_rented_indicator": true,
    "unit_monthly_actual_rent_amount": 2200,
    "unit_monthly_market_rent_amount": 2300
  }
],
"rental_summary": {
  "total_monthly_actual_rent_amount": 4600,
  "total_monthly_market_rent_amount": 7200
}

Plumb emits one PROPERTY_UNIT per unit, each with its own UNIT_RENT_SCHEDULE, a RENTAL_INFORMATION_SUMMARY on the PROPERTY, and an INCOME_APPROACH block under VALUATION_REPORT with the GRM. IncomeApproachIndicator and RentScheduleIndicator turn on automatically when the income-approach and rent-schedule data are present.

Honesty rules

Source of truth

The authoritative ingest contract is:

The internal schemas/{subject_property,comparable,appraisal}.schema.json files describe the emitted model your payload maps onto, a separate downstream layer. If a key is not listed in this spec, it is not yet supported on the ingest path. The fixture corpus under tests/integration/fixtures/ shows every supported archetype end-to-end and doubles as a regression gate against the GSEs' own SF1–SF5 passing samples.

Contact

Spec questions: hello@plumbvaluation.com. Importer integrations (TrueTracts, DataMaster, or any equivalent) are welcome.