Condos and units
How lookups handle buildings whose units are separate parcels, and what unit_required asks of you.
In many buildings, each unit is its own parcel with its own APN. An address without a unit number then doesn't identify one parcel. Verify doesn't pick a unit for you: it tells you a unit is needed and how many there are.
The flags
| Field | Meaning |
|---|---|
unit_required: true | The address has unit parcels, and the input named no unit that exists. |
unit_count | How many unit parcels the address has. Comes with unit_required. |
building_id | The ID the building's unit parcels share (bld_…). |
unit_required is left out of the response when it doesn't apply. Check match.unit_required === true rather than the status: it can come with matched or with matched_building.
What a lookup returns
| Input | Building has | Answer |
|---|---|---|
A unit that exists (APT 2) | Unit parcels | matched: the unit's parcel, its fieldgeist_id and the building_id. |
| No unit | Its own parcel and unit parcels | matched: the building's parcel, plus unit_required: true, unit_count and the building_id. |
| No unit, or a unit that doesn't exist | Only unit parcels | matched_building: no top-level parcel (fieldgeist_id: null), unit_required: true, unit_count, the building_id, and up to 10 units as candidates. |
A unit that doesn't exist (APT Z) | Its own parcel and unit parcels | matched_building: the building's parcel, unit_required: true and the building_id. |
A unit (APT 5) | No unit parcels | matched_building: the parcel at that address, without unit_required. The unit has no parcel of its own. |
Units are matched by their number (occupancyId); the designator isn't used, so APT 2, UNIT 2 and STE 2 all match unit 2. A compound unit such as B 4 is tried as written, then by its last part (4), with a slightly lower confidence.
Handling unit_required
What you do depends on who's on the other end:
- A person filling in a form: ask for the unit.
unit_counttells you whether to offer a picker (a few units) or a text field (many). - An agent: say the address needs a unit and stop, rather than choosing a candidate. That's the behavior
unit_requiredexists for. - A batch job: store the
building_idand flag the row for review. If you only need the building, thebuilding_id(and the building's parcel, when there is one) may be enough.
const match = await lookup(components);
if (match.unit_required) {
// Don't pick a unit. Ask for one, or keep the building.
return { needsUnit: true, buildingId: match.building_id, units: match.unit_count };
}
if (match.status === "matched") {
return { fieldgeistId: match.fieldgeist_id };
}Example
600 Pine St, Seattle WA 98109 without a unit, in a building with two unit parcels and no parcel of its own:
{
"status": "matched_building",
"fieldgeist_id": null,
"building_id": "bld_01JA2Z3Y4X5W6V7T8S9R0QPNMC",
"matchConfidence": 0.8,
"unit_required": true,
"unit_count": 2,
"candidates": [
{ "occupancyId": "1", "fieldgeist_id": "adr_01JA2Z3Y4X5W6V7T8S9R0QPNMD", "building_id": "bld_01JA2Z3Y4X5W6V7T8S9R0QPNMC", "...": "..." },
{ "occupancyId": "2", "fieldgeist_id": "adr_01JA2Z3Y4X5W6V7T8S9R0QPNME", "building_id": "bld_01JA2Z3Y4X5W6V7T8S9R0QPNMC", "...": "..." }
],
"...": "..."
}The same address with "occupancyType": "UNIT", "occupancyId": "2":
{
"status": "matched",
"fieldgeist_id": "adr_01JA2Z3Y4X5W6V7T8S9R0QPNME",
"building_id": "bld_01JA2Z3Y4X5W6V7T8S9R0QPNMC",
"matchConfidence": 1,
"candidates": [],
"...": "..."
}Values are illustrative. The full response is in Look up a parcel.