---
title: "Screen parcels by zoning"
method: GET
path: "/api/v1/zoning/search"
tags: ["Zoning"]
---

# Screen parcels by zoning

`GET /api/v1/zoning/search`

## Request

- Base URL: `https://propraven.com`
- URL: `https://propraven.com/api/v1/zoning/search`
- Auth: HTTP bearer

Parcels by exact raw code (case-sensitive), base code, overlay, derived family, or parsed ordinance attribute. Attribute filters EXCLUDE parcels whose code is unparsed, so an empty result means unknown, not none; `dictionary_warning` and `coverage` say how much was parsed. Unknown parameters are a 400. Account required.

## Query parameters

- `state_fips` string
- `county_fips` string
- `jurisdiction_id` string
- `raw_code` string
- `base_code` string
- `family` string
- `has_overlay` string
- `without_overlay` boolean
- `multifamily_by_right` boolean
- `adu_allowed` boolean
- `min_lot_area_sqft_max` number
- `max_height_ft_min` number
- `limit` integer
- `offset` integer

## Response `200`

Matching parcels with the coverage of the jurisdictions searched.

- object
  - `results` ParcelZoning[], required
    - `parcel` object, required
      - `stateFips` string
      - `countyFips` string
      - `parcelId` string
    - `matched` boolean, required: False when the parcel's centroid fell in no published district (a measurement, not an error).
    - `jurisdiction` object, nullable
      - `jurisdictionId` string, required: Registry id of the zoning body, e.g. `nc-37119-charlotte`.
      - `name` string, required
      - `type` 'city' | 'town' | 'village' | 'borough' | 'township' | 'county' | 'unincorporated' | 'consolidated' | 'special_district', required
      - `stateFips` string, required
      - `placeFips` string, nullable
      - `countyFips` string[]
      - `zoningHomeUrl` string, nullable
    - `boundaryJurisdiction` object, nullable
      - `jurisdictionId` string, required: Registry id of the zoning body, e.g. `nc-37119-charlotte`.
      - `name` string, required
      - `type` 'city' | 'town' | 'village' | 'borough' | 'township' | 'county' | 'unincorporated' | 'consolidated' | 'special_district', required
      - `stateFips` string, required
      - `placeFips` string, nullable
      - `countyFips` string[]
      - `zoningHomeUrl` string, nullable
    - `rawCode` string, nullable, required: THE FACT: the zoning code exactly as the issuing jurisdiction published it.
    - `baseCode` string, nullable
    - `codeName` string, nullable
    - `overlays` object[], required
      - `code` string
      - `kind` string
      - `name` string, nullable
      - `restrictionSummary` string, nullable
    - `splitZoned` boolean, nullable
    - `altCodes` string[]
    - `zonedSince` string, nullable
    - `match` object, required
      - `method` string
      - `confidence` number, nullable
      - `overlaysAvailable` boolean
    - `attributes` ZoningAttributes, required: The parsed ordinance dictionary for the code. EVERY value may be null: null means the ordinance has not been parsed for this code, or the text read does not state the value (or its quote did not verify). Null is never zero or false.
      - `minLotAreaSqft` number, nullable
      - `minLotWidthFt` number, nullable
      - `maxHeightFt` number, nullable
      - `maxStories` number, nullable
      - `maxFar` number, nullable
      - `maxDensityUnitsPerAcre` number, nullable
      - `maxLotCoveragePct` number, nullable
      - `setbackFrontFt` number, nullable
      - `setbackSideFt` number, nullable
      - `setbackRearFt` number, nullable
      - `minParkingPerUnit` number, nullable
      - `multifamilyByRight` boolean, nullable
      - `duplexByRight` boolean, nullable
      - `triplexQuadplexByRight` boolean, nullable
      - `aduAllowed` boolean, nullable
      - `shortTermRentalAllowed` boolean, nullable
      - `maxUnitsByRight` number, nullable
      - `permittedUseFamilies` string[], nullable
      - `conditionalUseFamilies` string[], nullable
      - `citations` object, required: Attribute name (e.g. `min_lot_area_sqft`) -> every record read for it, each with its section, verbatim quote and link.
      - `ordinanceVersion` string, nullable
      - `attributeSource` 'ordinance_text' | 'publisher_table' | 'manual' | 'none', required
      - `sourceCitation` string, nullable
      - `sourceUrl` string, nullable
      - `parsedAt` string, nullable
      - `reviewStatus` 'unreviewed' | 'machine' | 'human_verified' | 'disputed'
    - `attributesMatchedOn` 'raw_code' | 'base_code' | 'null', nullable
    - `conditionalNote` string, nullable
    - `derivedFamily` object
      - `family` string, nullable
      - `method` string
      - `confidence` number, nullable
      - `unresolvedReason` string
      - `evidence` string
    - `provenance` object
      - `sourceUrl` string, nullable
      - `publisherRole` string, nullable
      - `harvestedAt` string, nullable
      - `epochVersion` string, nullable
  - `count` integer, required
  - `limit` integer, required
  - `offset` integer, required
  - `coverage` ZoningCoverageRow[], required
    - `jurisdictionId` string, required
    - `jurisdictionName` string, required
    - `jurisdictionType` string
    - `stateFips` string
    - `countyFips` string[]
    - `servingStatus` 'served' | 'partial' | 'no_zoning' | 'failed' | 'registered', required: served = codes on parcels AND parsed ordinance attributes; partial = codes on parcels, attributes missing or incomplete; no_zoning = the body has no zoning ordinance; failed = could not be collected; registered = not yet attempted.
    - `statusReason` string, nullable
    - `statusAsOf` string, nullable
    - `parcelsInJurisdiction` integer, nullable
    - `denominatorMethod` 'boundary_centroid' | 'publisher_count' | 'unknown'
    - `parcelsMatched` integer, required
    - `parcelsUnmatched` integer
    - `matchRate` number, nullable, required
    - `distinctCodes` integer, required
    - `overlaysAvailable` boolean
    - `distinctOverlays` integer
    - `parcelsWithOverlay` integer
    - `parcelsSplitZoned` integer, nullable
    - `parcelsWithAttributes` integer
    - `parcelAttributeRate` number, nullable
    - `codesWithAttributes` integer, required
    - `codesMissingAttributes` integer
    - `dictionaryCompleteness` number, nullable, required
    - `primarySourceUrl` string, nullable
    - `lastHarvestedAt` string, nullable
  - `dictionary_warning` string

## Other responses

- `400`: A query or body parameter is invalid. Nothing was read or charged.
- `401`: Missing, malformed or invalid credential.
- `429`: Rate limit exceeded.
- `500`: Unexpected server error. The body never carries database or driver text.

---

[API](https://skmtc.dev/propraven/apis/propraven-api.md) · [All operations](https://skmtc.dev/propraven/apis/propraven-api/llms.txt) · [OpenAPI document](https://skmtc.dev/propraven/apis/propraven-api/revisions/37f8158c4eda?raw)
