---
title: "Combinable closed-catalog query. Scope required. Row-capped. Cursor-paginated."
method: POST
path: "/v1/query"
tags: ["query"]
---

# Combinable closed-catalog query. Scope required. Row-capped. Cursor-paginated.

`POST /v1/query`

## Request

- Base URL: `https://api.premiumpin.com`
- URL: `https://api.premiumpin.com/v1/query`
- Auth: one of:
  - HTTP bearer
  - API key in cookie `pp_session`

Provide a closed `q`, named `slots`, or a structured catalog `filter`; supplied controls combine with AND and are validated through the builder whitelist. A field not held by the scoped county returns an honest empty. Exactly one of scope.fips, scope.state, or scope.held is required; scope.held=[all] searches loaded non-Vermont counties. Omit-select rows include the 91 canonical_fields in schema order; unheld values are null. A named select keeps the requested keys and is not forced to 91. Metering: charges `search` (1) on accept and `record_reveal` per returned row. scope_coverage describes requested geography versus schema-bindable counties, independently of positive/zero rows and pagination. State scope uses the pinned current Census spine plus loaded historical counties, explicitly marked legacy. Wholly unloaded scope returns 400 county-not-held, not field-not-held or no matches.

## Headers

- `Idempotency-Key` string

## Request body

- QueryRequest
  - `cursor` string: opaque keyset cursor from a prior response. Bound to store_version + query; else 400/410.
  - `filter` Filter: Structured filter contract accepted by the public query builder.
    - `filters` object[]
      - `field` string, required
      - `op` 'eq' | 'ne' | 'in' | 'contains' | 'starts_with' | 'gt' | 'gte' | 'lt' | 'lte' | 'between' | 'is_null' | 'is_not_null', required
      - `value` unknown
    - `logic` 'and'
    - `order_by` object
      - `dir` 'asc' | 'desc'
      - `field` string
  - `limit` integer
  - `order_by` object
    - `dir` 'asc' | 'desc'
    - `field` string
  - `q` string: Closed English question over held catalog slots. Not freehand SQL.
  - `scope` union, required: REQUIRED. Exactly one of fips, state, or held bounds the search.
    - object
      - `fips` string[], required
      - `held` string[]
      - `state` string[]
    - object
      - `fips` string[]
      - `held` string[]
      - `state` string[], required
    - object
      - `fips` string[]
      - `held` string[], required
      - `state` string[]
  - `select` string[]: Return-field whitelist from the public field catalog. Private internal fields are never allowed.
  - `slots` object: Named closed-catalog slots. Combined with filter.filters using AND. tax_amount and subdivision_name are rejected.

## Response `200`

matching parcels (projected, PII-gated by entitlement, suppression-filtered)

- QueryResponse
  - `bindable_fips` string[]
  - `count` integer: rows returned (<= limit)
  - `empty_reason` 'field-not-held', nullable
  - `field_notes` FieldSourceNote[]
    - `capture_receipt_sha256` string, required
    - `effective_year` integer, nullable, required: Null when the field's effective year is unknown.
    - `field` string, required
    - `fieldbook_sha256` string, required
    - `fips` string, required
    - `parcel_universe_year` integer, required: Dataset membership year, not field effective year.
    - `release_manifest_sha256` string, required
    - `source_field` string, required
    - `source_url` string, uri, required
    - `stage_sha256` string, required
    - `warning` string, required
  - `honest_empty` boolean
  - `miss_reason` string, nullable
  - `next_cursor` string, nullable: pass as cursor for the next page; null on last page
  - `parcels` Parcel[]
    - `access_type` string, nullable
    - `acres` number, nullable
    - `ag_value` number, nullable
    - `assessed_value` number, nullable
    - `bedrooms` integer, nullable
    - `block` string, nullable
    - `building_type` string, nullable
    - `calc_area` number, nullable
    - `census_tract` string, nullable
    - `census_tract_name` string, nullable
    - `cooling` string, nullable
    - `county_fips` string, nullable
    - `county_name` string, nullable
    - `county_sub_fips` string, nullable
    - `county_sub_name` string, nullable
    - `deed_book` string, nullable
    - `deed_instrument` string, nullable
    - `deed_page` string, nullable
    - `elev_avg` number, nullable
    - `elev_max` number, nullable
    - `elev_min` number, nullable
    - `epa_dfr_url` string, nullable
    - `epa_frs_id` string, nullable
    - `fips` string, nullable
    - `fireplaces` integer, nullable
    - `firm_date` string, date, nullable
    - `firm_id` string, nullable
    - `flood_zone` string, nullable
    - `foundation` string, nullable
    - `full_baths` integer, nullable
    - `half_baths` integer, nullable
    - `heat_fuel` string, nullable
    - `heating` string, nullable
    - `improvement_value` number, nullable
    - `iucn_class` string, nullable
    - `land_use` string, nullable
    - `land_use_desc` string, nullable
    - `land_value` number, nullable
    - `legal_desc` string, nullable
    - `living_area_sqft` number, nullable
    - `lot` string, nullable
    - `market_value` number, nullable
    - `naics_code` string, nullable
    - `num_buildings` integer, nullable
    - `num_floors` integer, nullable
    - `num_units` integer, nullable
    - `owner_address` string, nullable
    - `owner_city` string, nullable
    - `owner_country` string, nullable
    - `owner_name` string, nullable
    - `owner_state` string, nullable
    - `owner_type` string, nullable
    - `owner_zip` string, nullable
    - `parcel_id` string, nullable
    - `parcel_id_alt` string, nullable
    - `parcel_id_original` string, nullable
    - `parcel_id_original_alt` string, nullable
    - `parcel_type` string, nullable
    - `parent_parcel_id` string, nullable
    - `permit_caa` string, nullable
    - `permit_cwa` string, nullable
    - `permit_rcra` string, nullable
    - `place_name` string, nullable
    - `place_type` string, nullable
    - `plss_desc` string, nullable
    - `prior_deed_book` string, nullable
    - `prior_deed_page` string, nullable
    - `quarter_section` string, nullable
    - `range` string, nullable
    - `roof_cover` string, nullable
    - `sale_date` string, date, nullable
    - `sale_price` number, nullable
    - `section` string, nullable
    - `siding` string, nullable
    - `site_address` string, nullable
    - `site_city` string, nullable
    - `site_state` string, nullable
    - `site_zip` string, nullable
    - `source_updated` string, date, nullable
    - `source_vintage` string, nullable
    - `stack_id` string, nullable
    - `state_fips` string, nullable
    - `static_bfe` number, nullable
    - `tax_account` string, nullable
    - `tax_district` string, nullable
    - `tax_year` integer, nullable
    - `township` string, nullable
    - `year_built` integer, nullable
    - `zoning_code` string, nullable
    - `zoning_desc` string, nullable
    - `zoning_subtype` string, nullable
  - `question_id` string, nullable
  - `scope_coverage` ScopeCoverage, required: Shared Engine availability for the effective existing filter and type rules. All FIPS arrays are sorted and deduplicated. For resolved supported filters, bindable/unavailable/field-unavailable are disjoint and exhaust requested_fips. Available means all requested counties bindable, partial a nonempty proper subset, unavailable none. Unknown means unresolved filter, with no certified bindable/unavailable/field-unavailable classification; it is never a fallback for missing or corrupt Census authority (generation binding fails). This does not promise visited counties, nonnull fields, distinct parcel totals, or legal access. Optional nullable projections retain existing binding rules.
    - `bindable_fips` string[], required: Eligible under existing required-field/type rules, not visited on this page.
    - `field_unavailable_fips` string[], required: Held geography lacking required capability.
    - `legacy_fips` string[], required: Loaded/requested historical codes outside pinned current authority; not successor-jurisdiction coverage.
    - `requested_fips` string[], required
    - `status` 'available' | 'partial' | 'unavailable' | 'unknown', required
    - `unavailable_fips` string[], required: Requested geography without a loaded table.
  - `store_version` string
  - `truncated` boolean: more rows exist beyond this page
  - `unavailable_fields` string[]: Named fields not held by the scoped county; present on field-not-held honest empties.

## Other responses

- `400`: bad filter / no scope / unknown field or op / malformed cursor / county-not-held for wholly unloaded search or absent lookup table
- `401`: missing or invalid API key / session
- `402`: metered quota exhausted (hard cap). Includes upgrade_url.
- `403`: requested owner-PII fields but the plan/entitlement doesn't allow them
- `410`: cursor was minted against an older snapshot; restart pagination
- `413`: scope would exceed the row/scan cap; narrow fips/state/held or add filters
- `429`: too many requests; retry after the window

---

[API](https://skmtc.dev/premiumpin/apis/premiumpin-property-records-api.md) · [All operations](https://skmtc.dev/premiumpin/apis/premiumpin-property-records-api/llms.txt) · [OpenAPI document](https://skmtc.dev/premiumpin/apis/premiumpin-property-records-api/revisions/18f5ec1c629c?raw)
