> ## Documentation Index
> Fetch the complete documentation index at: https://docs.propertylayer.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Data fields

> Every field PropertyLayer returns, section by section.

## Overview

A property record is everything the county recorded for a parcel: owner, address, structures, land, valuation, taxes and sale history, along with the boundary geometry, the PropertyLayer identifiers and the enrichment fields.

Every field is optional. If a value is null or missing, it was not published for that property. PropertyLayer does not estimate or infer.

***

## PropertyLayer identifiers and geometry

| Field | Type | Description |
| - | - | - |
| `bpd_uuid` | string | Unique PropertyLayer identifier for this property |
| `bpd_stack_uuid` | string | Groups properties sharing the same parcel geometry (e.g. condos) |
| `geoid` | string | 5-digit county GEOID (state FIPS + county FIPS) |
| `state` | string | Two-letter state abbreviation |
| `state_fp` | string | State FIPS code |
| `state_name` | string | Full state name |
| `county` | string | County name |
| `county_fp` | string | County FIPS code |
| `latitude` / `longitude` | number | Parcel centroid |
| `geom` | object | **Parcel boundary polygon** (GeoJSON) |

***

## Assessor identifiers (identity)

| Field | Type | Description |
| - | - | - |
| `parcel_id` | string | Assessor parcel number (APN) |
| `apn_formatted` | string | APN with the county's punctuation (e.g. `054-020-067-000`) |
| `apn_unformatted` | string | APN with punctuation stripped |
| `alt_ids[]` | array | Other identifiers the county carries, as `{ kind, value }`. Common kinds: `state_parcel_id`, `account_number`, `property_id`, `alternate_key`, `geographic_id`, `pin` |
| `geoid` | string | 5-digit county FIPS |
| `county_name` | string | County name |
| `state` | string | Two-letter state abbreviation |

## Owner (ownership)

| Field | Type | Description |
| - | - | - |
| `owner_name` | string | Primary owner |
| `owner_id` | string | County owner identifier |
| `owners[]` | array | Per-owner detail: `name`, `owner_type`, `role`, `percent_ownership`, `is_corporate`, `is_trust` |
| `care_of` | string | "care of" line |
| `mailing_address` | object | `line1`, `line2`, `city`, `state`, `zip`, `zip4` |
| `owner_occupied` | boolean | Owner occupancy as reported by the county |
| `owner_source` | string | Which county file the ownership came from |

## Property address (situs\_address)

| Field | Type | Description |
| - | - | - |
| `raw` | string | Address exactly as published |
| `line1`, `line2` | string | Street lines |
| `house_number`, `pre_direction`, `street_name`, `street_type`, `post_direction`, `unit` | string | Parsed components |
| `city`, `state`, `zip`, `zip4` | string | Locality |

## Classification

| Field | Type | Description |
| - | - | - |
| `property_type` | string | County property type, verbatim |
| `property_class_code` / `property_class_description` | string | Assessment class |
| `land_use_code` / `land_use_description` | string | Land use |
| `zoning` | string | Zoning code, verbatim |
| `roll_type` | string | Which assessment roll the record sits on |
| `is_vacant` | boolean | County-flagged vacancy |
| `is_use_value_enrolled` | boolean | Enrolled in a use-value / current-use program (e.g. agricultural) |

## Structure summary (building\_summary)

Rolled up across every structure on the property. Read this when you want one number per property.

| Field | Type | Description |
| - | - | - |
| `buildings_count` | integer | Number of structures |
| `mobile_homes_count` | integer | Mobile homes among them |
| `year_built` | integer | Year built |
| `effective_year_built` | integer | Effective year after renovation |
| `stories` | number | Stories |
| `bedrooms` | integer | Bedrooms |
| `baths_full` / `baths_half` | integer | Bathrooms |
| `baths_total_calc` | number | Computed total baths |
| `living_area_sqft` | integer | Living area |
| `universal_building_sqft` | integer | Best available building area |
| `universal_building_sqft_source` | string | Which measure `universal_building_sqft` came from: `living`, `total`, `gross`, `heated`, `ground`, `reported`, or `unknown` |

> [!NOTE]
>
> Counties measure building area differently. `universal_building_sqft` picks the best available measure per record and `universal_building_sqft_source` tells you which one, so you can hold the basis constant when comparing across counties.

## Structures (buildings\[])

One entry per structure, with whatever construction detail the assessor carries.

| Field | Type | Description |
| - | - | - |
| `building_type`, `description`, `architectural_style` | string | Structure type |
| `year_built`, `effective_year_built` | integer | Construction dates |
| `stories`, `units_count` | number / integer | Size |
| `bedrooms`, `baths_full`, `baths_half`, `baths_total_calc` | integer / number | Room counts |
| `living_area_sqft`, `total_area_sqft` | integer | Area |
| `basement`, `basement_area_sqft`, `finished_basement_sqft`, `attic` | string / number | Below and above grade |
| `garage`, `garage_area_sqft`, `carport`, `pool` | string / number | Site improvements |
| `condition`, `quality`, `construction_class`, `frame_type`, `foundation` | string | Construction grade |
| `exterior_wall`, `interior_wall`, `roof_cover`, `roof_shape`, `floor_cover` | string | Materials |
| `heating`, `heating_fuel`, `cooling`, `hvac_raw` | string | Mechanical |
| `occupancy` | string | Occupancy classification |

## Land

| Field | Type | Description |
| - | - | - |
| `acres`, `acres_calculated`, `acres_deeded` | number | Acreage as reported, computed, and deeded |
| `lot_sqft`, `lot_type` | number / string | Lot size and type |
| `frontage_ft`, `depth_ft`, `effective_frontage_ft`, `effective_depth_ft` | number | Dimensions |
| `land_method` | string | Valuation method |
| `site_condition`, `topography`, `view`, `access` | string | Site characteristics |
| `utilities` | object | `water`, `sewer`, `water_sewer`, `gas`, `electricity` |

## Valuation (valuation\_current, valuations\[])

`valuation_current` is the latest roll year. `valuations[]` is the full history, one entry per year.

| Field | Type | Description |
| - | - | - |
| `year` | integer | Roll year |
| `basis` | string | Which column the county published: `assessed`, `market`, `appraised`, or `taxable` |
| `assessed_total`, `assessed_land`, `assessed_improvements`, `assessed_net` | integer | Assessed values |
| `market_total`, `market_land`, `market_improvements` | integer | Market values |
| `appraised_total` | integer | Appraised value |
| `taxable_total` | integer | Taxable value |
| `land_value`, `improvement_value`, `total_value` | integer | Normalized land / improvement / total |
| `full_cash_value` | integer | Full cash value, where the state uses it |
| `exemption_amount` | integer | Exemptions applied |

`valuation_current` additionally carries `appraised_land`, `appraised_improvements`, `taxable_land`, `taxable_improvements`, `exempt_value`, and `homestead_value`.

> [!WARNING]
>
> States are not consistent about what "value" means. Read `basis` before comparing across state lines. A California `assessed` figure is constrained by Prop 13 and will not line up with a Texas `market` figure.

## Taxes

| Field | Type | Description |
| - | - | - |
| `tax_rate_area` | string | Tax rate area / district code |
| `total_mill_rate` | number | Combined mill rate |
| `is_delinquent` | boolean | Delinquency flag |
| `bills[]` | array | `year`, `pay_year`, `bill_type`, `statement_number`, `base_tax`, `gross_tax`, `net_tax`, `total_tax`, `amount_due`, `amount_paid`, `penalty_interest`, `mill_rate`, `payment_status` |
| `levies[]` | array | Per-authority levies: `year`, `authority`, `rate`, `amount`, `taxable_value` |

## Exemptions

| Field | Type | Description |
| - | - | - |
| `type` | string | Exemption name, verbatim (e.g. `Homeowners Exemption`, `Homestead`) |
| `code` | string | County exemption code |
| `description` | string | Longer description |
| `amount` | integer | Exempted value |
| `year` | integer | Roll year |

## Sale history (transfers\[])

Every recorded transfer the assessor carries.

| Field | Type | Description |
| - | - | - |
| `sale_date`, `recording_date` | date | Sale and recording dates |
| `price` | integer | Sale price |
| `market_value_at_sale` | integer | Assessed market value at the time |
| `buyer`, `seller` | string | Parties |
| `document_number`, `book`, `page` | string | Recording reference |
| `instrument_type` | string | Deed type, verbatim (e.g. `WD`, `WARRANTY DEED`, `QC`) |
| `transaction_type`, `qualification` | string | County transaction coding |
| `is_arms_length`, `is_nominal`, `is_quitclaim` | boolean | Normalized sale-quality flags |

> [!NOTE]
>
> Use `is_arms_length` to exclude intra-family transfers, quitclaims, and \$1 nominal deeds before computing price statistics.

## Legal description (legal)

| Field | Type | Description |
| - | - | - |
| `legal_description` | string | Full legal description |
| `subdivision` | string | Subdivision name |
| `block`, `lot` | string | Block and lot |
| `section`, `township`, `range` | string | PLSS references |
| `plat_book`, `plat_page`, `map_reference` | string | Plat references |

## Location

| Field | Type | Description |
| - | - | - |
| `latitude`, `longitude`, `point` | number / object | Assessor-published point |
| `census_tract` | string | Census tract |
| `municipality`, `township_name`, `ward` | string | Administrative geography |
| `neighborhood_code`, `neighborhood_name`, `market_area` | string | Assessor market/neighborhood coding |
| `flood_zone` | string | County-reported flood zone |

## Districts

Taxing and service districts: `{ kind, code, name }`. Common `kind` values are `tax_district`, `school`, `jurisdiction`, `city`, `municipality`, `township`, `county`, `special_service`, `fire`, `college`, `hospital`.

## Computed fields (derived)

PropertyLayer-computed roll-ups, present on every assessor record. Use these instead of walking the arrays yourself.

| Field | Type | Description |
| - | - | - |
| `has_building`, `has_sales`, `has_valuation_history` | boolean | Which sections are populated |
| `calculated_total`, `calculated_land`, `calculated_improvements` | integer | Best-available value, normalized across counties |
| `last_sale_date`, `last_sale_price` | date / integer | Most recent transfer |
| `valuation_years_count`, `valuation_earliest_year`, `valuation_latest_year` | integer | Span of the valuation history |

> [!NOTE]
>
> Use `calculated_total` when you need one comparable value per property nationwide. It reconciles counties that publish assessed, market, or appraised figures under different names.

## Flags and links

| Section | Fields |
| - | - |
| `flags` | `owner_redacted`, `in_ag_district`, `reappraisal_year` |
| `links` | `detail_url`, `gis_url`, `record_card_url`, `tax_bill_url`. Deep links back to the county's own record |

## Normalized vs. verbatim values

Most assessor string fields are passed through **exactly as the county publishes them**, with no cross-county normalization. `buildings.pool` alone appears as `No`, `NO`, `N`, `0`, `No Pool`, `Yes`, `Y`, `YES`, `Pool`, and more.

Normalized, cross-county-comparable fields are limited to:

* `derived.calculated_total` / `calculated_land` / `calculated_improvements`
* `derived.last_sale_date` / `last_sale_price`
* `derived.has_building` / `has_sales` / `has_valuation_history`
* `building_summary.universal_building_sqft` (with `universal_building_sqft_source`)
* `transfers[].is_arms_length` / `is_nominal` / `is_quitclaim`
* `identity.*` and `location.census_tract`

Everything else needs your own normalization layer if you are comparing across counties. That is a deliberate choice. Flattening each county's vocabulary into a shared one would throw away detail PropertyLayer has no way to recover.

## Schema versioning

Each assessor record carries a `schema_version`. Counties periodically publish attributes that are not yet in the PropertyLayer schema, and those get passed through on the relevant section rather than dropped. So treat every section as open: parse what you need and ignore the rest. The list above is not exhaustive.

***

***

## Enrichments

External datasets joined onto every property by PropertyLayer.

### USDA Cropland Data Layer (CDL)

| Field | Description |
| - | - |
| `cdl_majority_category` | Dominant crop or land cover type (e.g. `Corn`, `Soybeans`, `Developed`) |
| `cdl_majority_value` | Numeric USDA CDL category code |
| `cdl_majority_percent` | Percentage of parcel area covered by the majority CDL category |
| `cdl_raw` | Full per-category breakdown for the parcel |

The CDL is updated annually by USDA and covers all US agricultural land. Useful for filtering properties by crop type or separating agricultural from developed land at scale.

### FEMA flood zones

| Field | Description |
| - | - |
| `fema_flood_zone` | FEMA flood zone designation (e.g. `AE`, `X`, `VE`) |
| `fema_flood_zone_subtype` | Flood zone subtype where available |
| `fema_flood_zone_raw` | Raw FEMA FIRM data object for the parcel |

Zone `X` indicates minimal flood hazard. Zones beginning with `A` or `V` indicate Special Flood Hazard Areas (SFHA) where federal flood insurance may be required.

### Elevation and adjacency

| Field | Description |
| - | - |
| `elevation` | Centroid elevation in meters above sea level |
| `adjacent_acreage_sameowner` | Total contiguous acreage owned by the same owner |

`adjacent_acreage_sameowner` is useful for identifying large contiguous landholdings split across multiple parcel records.

### Building footprints (building\_footprints\[])

Opt in with `include_buildings: true`. Each entry is one structure from the ORNL building footprint dataset.

| Field | Type | Description |
| - | - | - |
| `build_id` | string | Unique building identifier |
| `height` | number | Building height in meters |
| `height_variance` | number | Uncertainty in the height estimate |
| `estimated_floors` | integer | Estimated number of floors |
| `geom` | object | Building footprint geometry (GeoJSON MultiPolygon) |

The key is omitted entirely when `include_buildings` was not requested, which says nothing about whether buildings exist.

> [!NOTE]
>
> `building_footprints` is ORNL footprint geometry and height. It is not the same as the assessor's `buildings` array, which carries per-structure construction detail: bedrooms, baths, roof, HVAC, year built.

***

## Null values

A null or absent value means that data was not published for the property. PropertyLayer does not estimate, impute, or infer missing values.

This is by design: a missing sale price means no sale was recorded, not that the property has never sold. A missing `classification.zoning` means zoning was not published.

**PropertyLayer retains all property records regardless of data completeness.** Some competitors remove parcels that fall below a minimum field threshold, which makes their counts appear lower. PropertyLayer keeps every record a county publishes, so counts reflect what the county actually recorded.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.