Docs

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

FieldMeaning
unit_required: trueThe address has unit parcels, and the input named no unit that exists.
unit_countHow many unit parcels the address has. Comes with unit_required.
building_idThe 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

InputBuilding hasAnswer
A unit that exists (APT 2)Unit parcelsmatched: the unit's parcel, its fieldgeist_id and the building_id.
No unitIts own parcel and unit parcelsmatched: the building's parcel, plus unit_required: true, unit_count and the building_id.
No unit, or a unit that doesn't existOnly unit parcelsmatched_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 parcelsmatched_building: the building's parcel, unit_required: true and the building_id.
A unit (APT 5)No unit parcelsmatched_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_count tells 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_required exists for.
  • A batch job: store the building_id and flag the row for review. If you only need the building, the building_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.

On this page