---
title: "Get the owners of a property"
method: GET
path: "/v3/property/owners"
tags: ["Property V3"]
---

# Get the owners of a property

`GET /v3/property/owners`

## Request

- Base URL: `https://api.whitepages.com`
- URL: `https://api.whitepages.com/v3/property/owners`
- Auth: API key in header `x-api-key`
- TypeScript: <https://skmtc.dev/whitepages/apis/whitepages-api-reference/docs/v3/property/owners/get.ts> (a function with typed inputs; its response is checked against the schema)

Retrieve the entities that own a property.

Name the property however you have it: a Whitepages identifier, an
address, or a parcel number. The answer is always one property's
owners. An address matching several properties resolves to the best
match, and the property comes back with `match_type` and
`confidence_score` so you can confirm it is the one you meant.

Owners arrive in a field named for their entity class, so a person
owner and a business owner never share a list. A class a later data
release adds appears as a new field; `owner_type` is what tells a
caller an owner exists that this version has no field for.

Person owners carry the same shape the person endpoints return and
link to their full person record. Business owners carry a name,
which is all the data holds for them today.

There is no paging: one response carries the owner lists in full as
far as the data goes. Person owners are capped upstream, so check
`result_metadata.person_owners.complete` before reading the list as
the whole ownership record. When it is `false`, an unreported
number of owners is missing and this version offers no way to
reach them.

`match_type` and `confidence_score` are how you tell a resolved
property from a ranked guess; treat anything short of an exact
match as a suggestion, and confirm the property through search
before acting on the ownership answer.

Several parcels can share one address, as a condominium or a
commercial building does. Such an address resolves to a single
parcel, and `result_metadata.parcel_resolution` reports which one
answered and whether the choice was forced. The match fields cannot
carry that: a parcel chosen from three at one address still matches
that address exactly. Where the parcel carries no standardized
address, or the candidate list reached its limit,
`parcel_resolution` reports the question as open rather than
answering it.

A parcel number is the other case. It names one parcel, so one
matching several properties is a `409` carrying the candidates
rather than a resolution, the same answer the details route gives.

## Query parameters

- `property_id` string, nullable: Whitepages property identifier (capital 'R' prefix) or address identifier (capital 'A' prefix). A parcel number goes in `apn` instead.
- `street` string, nullable: Street address line
- `city` string, nullable: City name
- `state_code` 'AL' | 'AK' | 'AZ' | 'AR' | 'AS' | 'CA' | 'CO' | 'CT' | 'DE' | 'DC' | 'FL' | 'GA' | 'GU' | 'HI' | 'ID' | 'IL' | 'IN' | 'IA' | 'KS' | 'KY' | 'LA' | 'ME' | 'MD' | 'MA' | 'MI' | 'MN' | 'MS' | 'MO' | 'MT' | 'NE' | 'NV' | 'NH' | 'NJ' | 'NM' | 'NY' | 'NC' | 'ND' | 'MP' | 'OH' | 'OK' | 'OR' | 'PA' | 'PR' | 'RI' | 'SC' | 'SD' | 'TN' | 'TX' | 'TT' | 'UT' | 'VT' | 'VA' | 'VI' | 'WA' | 'WV' | 'WI' | 'WY': Valid US State and Territory codes. This enum contains all valid two-letter codes for US states and territories. Used for parameter validation in API requests.
- `zipcode` string, nullable: Five-digit ZIP code
- `apn` string, nullable: Assessor's Parcel Number. Narrow it with `fips`, or with `state_code` where one state holds the parcel.
- `fips` string, nullable: Five-digit county FIPS code. Narrows the lookup to one county, whether it names a parcel number or an address. A parcel number is unique within a county rather than nationally, which `state_code` cannot resolve where two counties in a state record the same one.

## Response `200`

Owners retrieved successfully

- PropertyOwnersV3ResponseDto: Owners response: one property's owners. No pagination envelope. A page number beside a singular ``result`` would only read as a contradiction, and the owners arrive embedded in the property document from a single call with no cursor to follow. What ``result_metadata`` carries instead is completeness: the person list is capped upstream, so a caller needs to know whether the owners shown are all of them.
  - `result` PropertyOwnersV3Dto, required: The entities that own one property, split by entity class.
    - `property` PropertyContextV3Dto, required: Enough of a property to know which one the owners belong to. Identifying fields and the link to the rest. The owners endpoint answers a question about ownership, so carrying the full property record here would make the payload about the wrong thing.
      - `property_id` string, required: Unique property identifier
      - `address_id` string, nullable: Unique address identifier
      - `apn` string, nullable: Assessor's Parcel Number
      - `property_address` PropertyAddressV3Dto, required: A property's address, where it has one. Every part is nullable, because a property is not always something with a street address. The next data release publishes about 28 million parcels identified by parcel number and county instead: a house number appears on 1% of them, and a street, city, or ZIP on roughly half. The state is nullable too. The release notes guarantee a parcel number and a county on every property and never make that claim about the state, and a field required on an unverified guarantee is the one that fails on the release that breaks it. Requiring those parts is what keeps those properties out of the API today. Nullable costs a caller a null check; required costs everyone a breaking change on the release that loosens it, which is why it is settled now rather than when the data lands.
        - `full_address` string, nullable: Complete formatted address string. `null` for a property with no street address
        - `line1` string, nullable: Street address line (house number and street)
        - `city` string, nullable: City name
        - `state` string, nullable: Two-letter state code
        - `zip` string, nullable: 5-digit ZIP code
        - `house` string, nullable: House or building number
        - `street` string, nullable: Street name
        - `street_type` string, nullable: Street suffix (St, Ave, Blvd, etc.)
        - `county` string, nullable: County name
      - `property_purpose` string, nullable: What the property is used for. Observed values: Amusement, Apartment, Commercial, CondoCommercial, CondoResidential, DuplexTripexQuadplex, Exempt, Financial, Hospital, HotelMotal, Industrial, Office, Parking, Retail, Service, SingleFamilyOrTownhouse, Transport, Vacant, Warehouse. Upstream owns this value space and may send others as the data expands, so match on the values you handle and treat anything else as unrecognized rather than invalid.
      - `owner_occupied` string, nullable: Whether the owner lives at the property. Observed values: AbsenteeOwner, OwnerOccupied, Unknown. Upstream owns this value space and may send others as the data expands, so match on the values you handle and treat anything else as unrecognized rather than invalid.
      - `match_type` 'exact' | 'best match': How closely the returned property matches the address asked for. This service derives the value from a digest comparison it performs itself, so no data release can introduce a case it does not handle and the enum is correctly closed.
      - `confidence_score` integer, nullable: How confident the address match is, derived from `match_type`. `null` for an identifier lookup
      - `result_metadata` PropertyContextMetadataV3Dto, required: Where to read the full record for a property named in a response.
        - `details_url` string, required: Canonical Property Details URL for this property
    - `owner_type` string, nullable: Ownership class recorded for the property. A value naming a class with no matching owners field is how a caller learns an owner exists that this version does not break out. Observed values: Business, Individual. Upstream owns this value space and may send others as the data expands, so match on the values you handle and treat anything else as unrecognized rather than invalid.
    - `person_owners` PersonOwnerV3Dto[]: Individuals who own the property
      - `id` string, required: Unique person identifier
      - `name` string, required: Full name
      - `age` integer, nullable: Age in years
      - `current_addresses` AddressDto[]: Addresses the person currently lives at
        - `address_id` string, required: Unique address identifier
        - `full_address` string, required: Complete formatted address string
        - `city` string, required: City name
        - `state` string, required: Two-letter state code
        - `line1` string, required: Street address line (house number and street)
        - `zip` string, required: 5-digit ZIP code
      - `phones` PhoneNumber[]: Phone numbers linked to the person
        - `number` string, required
        - `type` 'mobile' | 'landline' | 'voip' | 'tollfree' | 'unknown', required: Enumeration of supported phone number types.
        - `score` integer, nullable, required: Confidence score 0-100 showing how strongly this phone is linked to the person. Higher scores mean a stronger match.
      - `emails` PersonEmailDto[]: Email addresses linked to the person
        - `email` string, required: Email address
        - `score` integer, nullable: Confidence score 0-100 showing how strongly this email is linked to the person. Higher scores mean a stronger match.
      - `company_name` string, nullable: Employer name
      - `job_title` string, nullable: Job title
      - `result_metadata` PersonResultMetadataV3Dto: Per-person metadata: details link and displayed-vs-additional counts.
        - `details_url` string, nullable: Canonical Person Details URL for this person, or `null` when the record has no canonical Whitepages person id
        - `phones` ListCountDto, required: Displayed-vs-additional count for one list on a search result.
          - `displayed` integer, required: Number of items returned in this list on this response
          - `additional` integer, required: Count of items linked to the person but not included in the response (i.e. upstream_total minus displayed)
        - `emails` ListCountDto, required: Displayed-vs-additional count for one list on a search result.
          - `displayed` integer, required: Number of items returned in this list on this response
          - `additional` integer, required: Count of items linked to the person but not included in the response (i.e. upstream_total minus displayed)
    - `business_owners` BusinessOwnerV3Dto[]: Business entities that own the property
      - `name` string, required: Business entity name
  - `result_metadata` PropertyOwnersResultMetadataV3Dto, required: What the owner lists on this response do and do not account for.
    - `person_owners` OwnerListCountV3Dto, required: How many owners one list carries, and whether that is all of them.
      - `displayed` integer, required: Number of owners returned in this list
      - `complete` boolean, required: `true` when this list is every owner of that class on record. `false` when the upstream owner limit was reached and an unknown number were withheld; the count withheld is not reported upstream, and the remaining owners are not retrievable in this version
    - `business_owners` OwnerListCountV3Dto, required: How many owners one list carries, and whether that is all of them.
      - `displayed` integer, required: Number of owners returned in this list
      - `complete` boolean, required: `true` when this list is every owner of that class on record. `false` when the upstream owner limit was reached and an unknown number were withheld; the count withheld is not reported upstream, and the remaining owners are not retrievable in this version
    - `parcel_resolution` ParcelResolutionV3Dto, required: Which parcel answered, when the request could name several. Parcels compete when they carry the same standardized address. A unit address is a different address, so `2201 3rd Ave Apt 1406` answers with its own parcel and is not counted against a request for `2201 3rd Ave`. Only a request that describes an address is assessed: naming a `property_id` or an `apn` selects a parcel outright, and the fields below report that nothing was weighed rather than that the parcel stands alone at its address.
      - `matched` integer, nullable, required: Number of parcels carrying the same standardized address as the one that answered. One address can carry several, as a commercial building does. Parcels at a contained address, such as a unit within a building, carry a different address and are not counted. `null` when no count was taken, either because the request named a parcel rather than describing an address or because the resolved property carries no standardized address to compare. Read it with `complete`: a count taken from a truncated candidate list is a floor rather than a total
      - `resolved` string, required: Property ID of the parcel these owners belong to
      - `ambiguous` boolean, nullable, required: `true` when the request described an address that several parcels share, so the owners returned are one parcel's rather than the address's. Request the property by its `property_id` to name a parcel outright. `false` means uniqueness at that address was established. `null` means it was not assessed, never that the parcel is unique: a request naming a parcel is answered `null` because no search for parcels sharing its address ran
      - `complete` boolean, required: `true` when every parcel sharing the address was examined, so `matched` is a total. It is never `true` beside a `matched` of `null`. `false` when they were not, because the candidate list reached its limit and a further parcel may share the address unseen, because the request named a parcel and no such search ran, or because the resolved property carries no standardized address to examine anything against

## Other responses

- `400`: Bad Request
- `403`: Forbidden
- `404`: Not Found
- `409`: Conflict
- `422`: Unprocessable Content
- `429`: Too Many Requests
- `500`: Internal Server Error

## Changes

- **2026-10-28** `b22cd77a87be`: 2 breaking, 2 info
  - response property `result_metadata/parcel_resolution/ambiguous` list-of-types was widened by adding types `null` to media type `application/json` of response `200`
  - response property `result_metadata/parcel_resolution/matched` list-of-types was widened by adding types `null` to media type `application/json` of response `200`
  - added the non-success response with the status `409`
  - added the required property `result_metadata/parcel_resolution/complete` to the response with the `200` status
- **2026-10-23** `e2dc46cff897`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/whitepages/apis/whitepages-api-reference/changes/v3/property/owners/get.md)

---

[API](https://skmtc.dev/whitepages/apis/whitepages-api-reference.md) - [All operations](https://skmtc.dev/whitepages/apis/whitepages-api-reference/llms.txt) - [OpenAPI document](https://skmtc.dev/whitepages/apis/whitepages-api-reference/revisions/b22cd77a87be?raw)
