# Property Characteristics API - Owner, Risk, Home Prices (`nabeelbaghoor/property-characteristics-api`) Actor

Resolve any US address to a persistent property id, then read the full land and structure profile: land use, lot size, living area, beds, baths, construction, roof and foundation, owner occupancy, roof age and climate risk, plus listing, sales, rent and home price trends.

- **URL**: https://apify.com/nabeelbaghoor/property-characteristics-api.md
- **Developed by:** [Nabeel Hassan](https://apify.com/nabeelbaghoor) (community)
- **Categories:** Real estate, Business, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $16.00 / 1,000 property record returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Property Characteristics API - Owner, Risk, Home Prices

Turn a US street address into a persistent property id, then read everything the record holds: land, structure, ownership, roof age, climate risk, and the market around it.

### What this actor does

- **Address to property id.** Resolve a street address to the provider's persistent numeric property identifier, with the standardised address, parcel number, county FIPS, owner name and coordinates. That id is stable, so it is the right key to store against your own records.
- **Full characteristics profile.** Land use and category, lot size in acres and square feet, living and building area, bedrooms, bathrooms, stories, building count, construction type, exterior wall, roof type and cover, foundation, basement area, garage spaces, pool, and owner occupancy and absentee flags.
- **Honest year built.** The provider marks a year built that its model estimated rather than the county recorded. Every row says which it is, in a `yearBuiltIsEstimated` column, so an estimate never reads as a fact.
- **Roof age and climate risk.** Estimated roof age with its confidence rank, and multi-peril risk across flood, wildfire, hurricane, tornado, hail, wind, heat and drought, with the perils actually returned named on the row.
- **Market trends.** Listing activity, closed sales, rents, the home price index and its forecast, for a ZIP, county, metro or state, over a month range or at the latest reading.
- **Pay per result.** You are charged for rows that carry a real record. Resolving an address to an id is free, and addresses the provider matches nothing to are free.

### Bring your own key

This actor signs in with **your own client id and client secret**. Paste them into the input, or set the secret as `DATA_API_KEY`. Nothing runs on anyone else's credentials, and a run without them ends cleanly with an explanation rather than failing. A run also checks up front whether your credentials may call the dataset you picked, and stops with the list of the ones they can, rather than spending anything to find out.

### Example output

```json
{
  "recordType": "property-characteristics",
  "requested": "3001 Hackberry Rd, Irving, TX 75063",
  "found": true,
  "propertyId": "123456789",
  "landUse": "Single Family Residence",
  "lotAcres": 0.19,
  "lotSquareFeet": 8276,
  "yearBuilt": 2012,
  "yearBuiltIsEstimated": false,
  "livingSquareFootage": 2450,
  "bedrooms": 4,
  "totalBathrooms": 3,
  "stories": 2,
  "buildingCount": 1,
  "constructionType": "Wood Frame",
  "roofType": "Gable",
  "roofCover": "Composition Shingle",
  "foundation": "Slab",
  "garageSpaces": 2,
  "ownerOccupied": true
}
```

### FAQ

#### What is the property id and why does it matter?

It is the provider's persistent numeric identifier for a US parcel, assigned to every residential and commercial property. Unlike an address it does not change when a street is renamed or a unit is renumbered, and unlike a parcel number it is unique nationally rather than per county. Every property dataset in this actor is keyed on it, which is why an address is resolved to one first.

#### Do I have to give a property id, or can I use an address?

Either. Put full street addresses in the input and the actor resolves each one before reading the dataset you asked for. That resolving step uses the provider's own identity lookup and is not charged by this actor. Lines that are already numeric ids skip it entirely, which is faster and exact.

#### How do I know whether the year built is real?

Check the `yearBuiltIsEstimated` column. The provider flags a construction year that came from its own model rather than from a county record, and this actor surfaces that flag on every characteristics and roof age row. Treat an estimated year as a statistical estimate, not as a document.

#### What climate perils are covered?

Flood, wildfire, hurricane, tornado, hail, wind, heat and drought, with current scores and forward projections under different emissions scenarios and time horizons. Which perils come back depends on where the property is and what your agreement includes, so each row names the perils that were actually returned rather than showing empty columns for the rest.

#### Can I get market data for a whole metro?

Yes. Switch to one of the five market modes and set the area type to metro CBSA code, county FIPS, ZIP or state, then list the areas. One run can cover many areas at once. Add a from and to month to get a time series, or leave both empty for the latest reading. A range needs both ends, and the actor tells you rather than sending a half-filled one.

#### Does it cover commercial property?

Property characteristics covers both residential and commercial parcels. Climate risk, roof age and all five market datasets are US residential only, which is the provider's own scope.

#### What does it cost?

Pricing is pay per result: 0.016 USD per property identity or characteristics record, 0.012 USD per roof age or climate risk reading, and 0.008 USD per market reading, with Apify platform usage included. Rows the provider found nothing for are not charged. You also need your own agreement with the data provider, which bills separately and licenses each dataset separately.

#### Does the actor fail if my credentials are wrong?

No. Missing credentials, rejected credentials, a dataset that is not on your agreement, or an empty input all end the run cleanly with a message saying what to change. Only a real outage or a bug fails the run.

### Keyword map

property characteristics API, property data API, US property records, address to property id, CLIP identifier, parcel level identifier, property ownership data, owner occupied flag, absentee owner data, building characteristics API, roof age data, roof condition estimate, climate risk API, multi-peril risk scores, flood wildfire hurricane hail risk, property insurance underwriting data, home price index API, HPI forecast, housing market trends by ZIP, rental market data API, days on market data, mortgage collateral data, MISMO property data

***

*Note: this actor was built against the provider's published developer documentation. Its endpoints and tool names are transcribed from that documentation and have not been exercised against a live account, because no production credential exists for it.*

# Actor input Schema

## `mode` (type: `string`):

The first four options describe a property and read the list below. The last five describe a market and read a geography instead. Each dataset is licensed separately, so a run checks up front whether your credentials may call the one you picked.

## `properties` (type: `array`):

Property modes. One per line, either a full street address such as "3001 Hackberry Rd, Irving, TX 75063" or a numeric property id from an earlier run. An address is resolved to an id first, and that resolving step is not charged.

## `geographyType` (type: `string`):

Market modes. Which level of geography the values below are at.

## `geographyValues` (type: `array`):

Market modes. One value per line, matching the area type above, for example 06037 for Los Angeles County. A single run can cover many areas at once.

## `fromMonth` (type: `string`):

Market modes, optional. The first month of the range, written as YYYY-MM. A range needs both ends: leave both empty for the latest available reading.

## `toMonth` (type: `string`):

Market modes, optional. The last month of the range, written as YYYY-MM. A range needs both ends: leave both empty for the latest available reading.

## `useTestEnvironment` (type: `boolean`):

Sends the run to the provider's UAT host instead of production. Use this while you are validating an integration, with the UAT credentials the provider issued you.

## `maxResults` (type: `integer`):

The most rows this run will save and charge for. A market run over a long date range returns one row per area per month, so allow room for those.

## `requestsPerMinute` (type: `integer`):

How fast to call the provider. Lower this if your agreement rate limits the run.

## `clientId` (type: `string`):

Your own client id for the property intelligence provider. This actor is bring your own key: it signs in with your credentials only, and never uses anyone else's.

## `clientSecret` (type: `string`):

Your own client secret for the property intelligence provider. Exchanged for a short lived access token at the start of every run and stored as a secret.

## Actor input object example

```json
{
  "mode": "characteristics",
  "geographyType": "county_fips_code",
  "useTestEnvironment": false,
  "maxResults": 500,
  "requestsPerMinute": 60
}
```

# Actor output Schema

## `records` (type: `string`):

One row per record, alongside the address, property id or market area that produced it.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("nabeelbaghoor/property-characteristics-api").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("nabeelbaghoor/property-characteristics-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call nabeelbaghoor/property-characteristics-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nabeelbaghoor/property-characteristics-api"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/uWnMY4TgYmcvllfFB/builds/2IbuM5jjQfYy63Ghe/openapi.json
