Look up a parcel
Match a parsed street address to its parcel, or learn why it can't be matched to exactly one.
POST https://api.fieldgeist.com/v1/verify/lookupMatches a street address to a parcel and returns its Fieldgeist ID, county APN, county FIPS code and coordinates. When the address fits more than one parcel, or the building has unit parcels and no unit was given, the answer says so (ambiguous, unit_required) and lists candidates instead of picking one.
Send either the components of an address or a whole parse response.
Authentication
Authorization: Bearer <key>. See Authentication.
Request body
The body is a JSON object in one of two forms:
- A parse response, unchanged:
{"type": "street", "components": {...}, ...}. Onlytypeandcomponentsare read. - Bare components:
{"addressNumber": "400", "streetName": "BROAD", ...}, optionally with"type". Withouttype, the address is treated as a street address.
| Field | Type | Required | Description |
|---|---|---|---|
streetName | string | Yes | Street name. |
zip5 | string | One of zip5 or city | 5-digit ZIP Code. The fastest and most precise way to locate the address. |
city | string | One of zip5 or city | City. With state, or alone when the city's name exists in only one state. |
state | string | No | Two-letter state code. Needed with city when the city's name exists in more than one state. |
addressNumber | string | No | House number. Without it, the answer can only be a parcel with no house number (no_situs_parcel) or not_found. |
addressNumberSuffix | string | No | Such as 1/2. |
predirectional, postdirectional | string | No | Street directions, such as W or NW. |
streetSuffix | string | No | Street type, such as ST. Leave it out only if you don't know it: without it, every suffix at that house number is a candidate. |
occupancyType, occupancyId | string | No | Unit designator and number. The unit number picks a unit parcel in a building that has them. |
zip4 | string | No | Accepted, not used for matching. |
type | string | No | Address type from a parse. Anything other than street is refused with 422 unsupported_type. |
Values can be strings or numbers. Case and punctuation don't matter: values are normalized the same way the parcel index is.
Request example
curl https://api.fieldgeist.com/v1/verify/lookup \
-H "Authorization: Bearer $FIELDGEIST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"addressNumber": "400",
"streetName": "BROAD",
"streetSuffix": "ST",
"city": "SEATTLE",
"state": "WA",
"zip5": "98109"
}'Response
Parcel values on this page (IDs, APNs, coordinates) are illustrative.
200 OK: matched
{
"status": "matched",
"fieldgeist_id": "adr_01JA2Z3Y4X5W6V7T8S9R0QPNMA",
"building_id": null,
"apn": "198520-0495",
"fips": "53033",
"lat": 47.620494,
"lon": -122.349235,
"matchConfidence": 1,
"candidates": [],
"searched": ["matchkey/v3.2/zip5=98109/part.parquet"],
"readPath": "chunk",
"fuzzy": false
}| Field | Type | Description |
|---|---|---|
status | string | The outcome. See Statuses. |
fieldgeist_id | string | null | The matched parcel's Fieldgeist ID (adr_…). null when there is no single parcel. |
building_id | string | null | The building's ID (bld_…) when the address has unit parcels. See Condos and units. |
apn | string | null | The county's assessor parcel number, as the county writes it. |
fips | string | null | 5-digit county FIPS code. |
lat, lon | number | null | Coordinates of the parcel. |
matchConfidence | number | 0 to 1. How closely the input matched the parcel. 0 when there's no single parcel (ambiguous, not_found); each candidate then has its own. See Match confidence. |
unit_required | boolean | Present and true when the address has unit parcels and the input named no unit that exists. |
unit_count | number | Present with unit_required: how many unit parcels the address has. |
candidates | object[] | Other parcels that fit, up to 10. Empty for a clean single match. See Candidates. |
fuzzy | boolean | true when the street name matched as a near miss (a typo or variant) rather than exactly. Confidence is lowered. |
state_inferred | string | Present when you sent a city without a state or ZIP: the state the city was found in. |
searched | string[] | Diagnostic: which parts of the index were read. |
readPath | string | Diagnostic: how the answer was found (chunk, fuzzy_chunk, whole, fuzzy, none). |
Statuses
status | Meaning | Top-level parcel fields | What to do |
|---|---|---|---|
matched | One parcel fits. | Set | Use it. Check unit_required and fuzzy. |
matched_building | The building matched, but not a unit parcel. Either the input named a unit that has no parcel of its own (the answer is the building's parcel), or the building has only unit parcels and the input named none of them (no top-level parcel; the units are the candidates). | The building's parcel, or null with unit candidates | Use the building's parcel if that's enough. If unit_required is true, ask for the unit. |
ambiguous | Two or more different parcels fit equally well, for example 3 SPRUCE when there's a 3 SPRUCE ST and a 3 SPRUCE CT. | null | Show the candidates, or ask for the missing part (usually the suffix or a direction). |
no_situs_parcel | A weak match. The input had no house number, so the answer is a parcel on that street; or, in a single-ZIP search, the house number isn't on the street and the street has exactly one parcel with no house number on record. | Set | Don't treat it as a match without checking. matchConfidence is low. |
not_found | No parcel fits. | null | Check the input. Billed like any answer. |
200 OK: ambiguous
{
"status": "ambiguous",
"fieldgeist_id": null,
"building_id": null,
"apn": null,
"fips": null,
"lat": null,
"lon": null,
"matchConfidence": 0,
"candidates": [
{
"apn": "1234-0001",
"fips": "53033",
"lat": 47.611,
"lon": -122.335,
"zip5": "98101",
"addressNumber": "3",
"streetName": "SPRUCE",
"streetSuffix": "CT",
"occupancyId": null,
"matchConfidence": 0.85,
"fieldgeist_id": "adr_01JA2Z3Y4X5W6V7T8S9R0QPSP1",
"building_id": null
},
{
"apn": "1234-0002",
"fips": "53033",
"lat": 47.612,
"lon": -122.336,
"zip5": "98101",
"addressNumber": "3",
"streetName": "SPRUCE",
"streetSuffix": "ST",
"occupancyId": null,
"matchConfidence": 0.85,
"fieldgeist_id": "adr_01JA2Z3Y4X5W6V7T8S9R0QPSP2",
"building_id": null
}
],
"searched": ["matchkey/v3.2/zip5=98101/part.parquet"],
"readPath": "chunk",
"fuzzy": false
}The input was {"addressNumber": "3", "streetName": "SPRUCE", "zip5": "98101"}. With "streetSuffix": "CT" the same request returns matched.
200 OK: unit required
A condo building whose units are separate parcels, looked up without a unit:
{
"status": "matched_building",
"fieldgeist_id": null,
"building_id": "bld_01JA2Z3Y4X5W6V7T8S9R0QPNMC",
"apn": null,
"fips": null,
"lat": null,
"lon": null,
"matchConfidence": 0.8,
"unit_required": true,
"unit_count": 2,
"candidates": [
{
"apn": "777-1",
"fips": "53033",
"lat": 47.61,
"lon": -122.31,
"zip5": "98109",
"addressNumber": "600",
"streetName": "PINE",
"streetSuffix": "ST",
"occupancyId": "1",
"matchConfidence": 0.8,
"fieldgeist_id": "adr_01JA2Z3Y4X5W6V7T8S9R0QPNMD",
"building_id": "bld_01JA2Z3Y4X5W6V7T8S9R0QPNMC"
},
{
"apn": "777-2",
"fips": "53033",
"lat": 47.61,
"lon": -122.31,
"zip5": "98109",
"addressNumber": "600",
"streetName": "PINE",
"streetSuffix": "ST",
"occupancyId": "2",
"matchConfidence": 0.8,
"fieldgeist_id": "adr_01JA2Z3Y4X5W6V7T8S9R0QPNME",
"building_id": "bld_01JA2Z3Y4X5W6V7T8S9R0QPNMC"
}
],
"searched": ["matchkey/v3.2/zip5=98109/part.parquet"],
"readPath": "chunk",
"fuzzy": false
}Sending "occupancyId": "2" returns matched with that unit's parcel (adr_…NME) and the same building_id. A building that has its own parcel and unit parcels returns matched with the building's parcel plus unit_required: true. See Condos and units.
unit_required can come with matched or matched_building. Check the flag, not the status.
Candidates
Each candidate is a parcel that fits the input:
| Field | Type | Description |
|---|---|---|
fieldgeist_id | string | null | The parcel's Fieldgeist ID. |
building_id | string | null | Its building's ID, for unit parcels. |
apn, fips, lat, lon | As at the top level. | |
zip5, addressNumber, streetName, streetSuffix, occupancyId | string | null | The parcel's address as the index records it, so you can tell candidates apart. |
matchConfidence | number | How closely the input matched this candidate. |
fuzzy | boolean | Present and true when this candidate's street name was a near miss. |
Candidates are capped at 10 per answer; unit_count gives the full number of units.
City without a ZIP
Without zip5, the lookup searches the city. When the city's name exists in only one state, the state can be left out and the answer includes state_inferred:
{ "status": "matched", "fieldgeist_id": "adr_…", "state_inferred": "TX", "...": "..." }When the name exists in several states, the request is refused:
{
"error": "location_required",
"message": "city is in 3 states: add a state or zip5",
"states": 3
}Errors
| Status | error | Cause |
|---|---|---|
400 | invalid_json | The body isn't valid JSON. |
400 | components_required | The body isn't an object, or a component is not a string or number. |
400 | street_required | No streetName. |
400 | location_required | Neither zip5 nor city, or a city that exists in more than one state without a state. The second case adds states. |
422 | unsupported_type | type isn't street (PO boxes, rural routes and other types have no parcel). The response echoes type. |
500 | internal_error | The lookup failed on our side. Retry. |
503 | matchkey_unavailable | The parcel index is unavailable. Retry later. |
401, 402, 403, 429 | See Errors. |
{
"error": "unsupported_type",
"type": "po_box",
"message": "only type=street addresses can be matched to a parcel"
}