whohouse.io

Property records API

Look up recorded owners, sales and mortgage history by address. API access is included in every paid plan.

Get an API key

Download the OpenAPI specification

Authentication

Create a key in your workspace’s API keys page. Send it as a bearer token. Keys belong to a workspace and use the same monthly credits as browser lookups.

Authorization: Bearer wh_live_your_key

Keep keys on your server. Reading results requires lookup:read; submitting lookups requires lookup:write. You can revoke a key from your workspace.

Look up addresses

POST/api/v1/batches

Send up to 1,000 addresses in a batch. Formatting and common abbreviations are normalized before matching. Include city and state, or ZIP, whenever possible.

Request
curl https://whohouse.io/api/v1/batches \
  -H 'Authorization: Bearer wh_live_your_key' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: your-unique-batch-id' \
  -d '{"addresses":["3785 n 192nd ter elkhorn , ne"]}'

The API returns 202 Accepted with a job ID and status. Use a stable Idempotency-Key when retrying the same request to avoid creating a second job.

{ "id": "job_example", "status": "queued", "total": 1 }

For one address, use POST /api/v1/lookup with {"address":"104 Example St, Omaha, NE"}. It returns a job in the same format and requests the full record, consuming credits on a successful owner match.

Source responses are cached server-side for up to 24 hours. A fresh cache hit avoids a new provider request. Job acceptance and result readiness are separate timings; cold lookups depend on the source. No fixed response-time SLA is offered.

Get results

GET/api/v1/batches/{id}

Poll with a short delay until the job’s status is completed. Results preserve input order. Each address has its own status, so a missing owner record does not discard the rest of your batch.

Completed result · illustrative
{
  "job": {
    "id": "job_example",
    "status": "completed",
    "total": 1,
    "completed": 1,
    "matched": 1
  },
  "items": [
    {
      "index": 0,
      "input": "104 Example St, Omaha, NE",
      "status": "matched",
      "result": {
        "address": "104 Example St, Omaha, NE",
        "owner": {
          "name": "[recorded name]",
          "relationship": "recorded_owner",
          "label": "Recorded owner",
          "source": "County property record"
        },
        "property": {
          "propertyType": "Single-family home"
        },
        "source": {
          "name": "County property record",
          "updatedAt": null,
          "retrievedAt": "2026-09-12T12:00:00Z"
        }
      }
    }
  ],
  "pagination": {
    "limit": 100,
    "offset": 0,
    "total": 1
  }
}

sales contains recorded buyers, sellers, prices and sale dates. mortgages contains dated source loan records, including borrowers, lenders, amounts, status, rates and balances when supplied. valuation holds source estimates; photos holds available image URLs and attribution. Missing fields are omitted, not filled with guesses. A past sale may contain only a date; it does not establish a chain of title.

Results are paginated: use ?offset=0&limit=100, with a maximum limit of 1,000. Download a CSV from GET /api/v1/batches/{id}/export.csv. The sales, mortgages, valuation, photos and source_by_field CSV columns contain JSON so repeated records and their dates are preserved.

owner_unavailable means property facts were found but no owner name was returned. not_found, ambiguous, and invalid mean the address needs review. Only successful owner lookups use credits. Repeated matches to the same property in a workspace’s billing period don’t count again; missing owners, ambiguous matches, and unsuccessful lookups are free. A submission reserves credits while it runs, so a batch must fit within the available balance. Unused reservations are released when the work finishes.

Source dates are reported separately from retrieval dates. A recorded buyer is identified as a buyer, and a normalized address does not establish current ownership. Results are retained for 30 days, up to 500 completed jobs per workspace.

Errors and limits

StatusMeaning
400Check the address list and request format.
401The API key is missing or invalid.
402The workspace’s lookup allowance is exhausted.
403Check workspace access, membership, key scopes, and plan eligibility.
409An idempotency key was reused with a different request.
429A request limit has been reached. Follow the response details before retrying.
503A source is temporarily unavailable.

Use bounded concurrency and retry temporary failures with a delay. Individual item failures appear in the job results. There are no automatic overage charges.

Compare plans