Developers · REST API

Property Data API

191.3M US property records. RESTful JSON API with parcel search, owner intelligence, permits, deeds, and market analytics.

PropRaven is one verified parcel dataset delivered three ways — this REST API, a Snowflake Marketplace share, and bulk Parquet and CSV delivery — and the same record is byte-identical across all of them. The API is the right door when you need a parcel, an owner or a cohort inside an application: one HTTPS call returns the owner of record, assessed value, last sale, permits, deed history and hazard risk for any of the 191.3M parcels in the serving set, with an official client in Python, TypeScript and Go and a hosted Model Context Protocol server for AI agents.

What the API returns

The v1 surface is organised into the endpoint groups below — the tags of the published OpenAPI 3.1 specification, which currently describes 46 paths. Every response is JSON, every parcel is addressed by its composite county_fips:parcel_id identifier, and every record carries the serving epoch it was published from, so two callers asking for the same parcel on the same day get the same bytes.

GroupWhat it returns
ParcelsOne parcel by ID, plus its owner, permits, deed history, risk assessment, traffic history, GeoJSON polygons for a bounding box, and the paid dossier / comp pack / risk score.
SearchParcel search by bounds, filters and sorting; full paginated text + attribute search; address / place / parcel autocomplete; CSV export of a result set.
CoverageCoverage statistics — where PropRaven has parcel data, by state and county.
DealsAbsentee owners, flips, contractors by permit activity, entity-owned parcels, high land-to-improvement ratio, lender profiles, long-held parcels, portfolio owners, county-quarter transaction summaries.
LeadsA lead feed priced per lead, with a free masked preview of count, price and sample.
MarketCounty market statistics, a single-county detail view, market trends, and flip activity grouped by county.
OwnersOwner search by name, owner profile, the owner's properties, portfolio summary, recorded deed transactions, and the paid owner intelligence report.
WebhooksCreate, list, inspect and disable webhook endpoints, and read recent delivery attempts.
AccountCurrent-period usage and quota for your key.
StorefrontThe sealed field catalog and try-before-buy availability quotes — the free discovery surface agents read first.
CreditsFund and read a prepaid credit balance over x402.
WatchCreate a watch on a parcel or cohort (free) and poll it for new changes.
VerifyVerify facts for one parcel, or in batch, with a free preview.

Getting Started

  1. 1Create an account at propraven.com/sign-up
  2. 2Generate an API key at Settings > API Keys
  3. 3Make your first request (see examples below)

The Free plan is $0 with 1,000 lookups a month and no card required. New accounts land on /developers/welcome with the key on screen.

Authentication

Include your API key in the Authorization header:

Authorization: Bearer pz_your_key_here

Keys are prefixed pz_ and are the only credential the API uses — there is no OAuth dance for server-to-server calls, and the same key authenticates the SDKs and the hosted MCP server. A key is required on every endpoint except the free discovery surface (coverage statistics, the storefront catalog and availability quotes, and lead-feed previews) and the x402-paid resources, which accept a signed wallet payment instead of a key. Being authenticated is not the same as being entitled: a free-tier key asking for a paid dossier gets the same HTTP 402 an anonymous caller does.

Keys are created and revoked self-serve under Settings > API Keys. Treat them as secrets — never ship one in a browser bundle. For the supply-chain side (SLSA provenance on every SDK and MCP release, OIDC trusted publishing) see Security.

Code Examples

The raw HTTP surface needs nothing but a key. The single-parcel lookup below is the first call most integrations make; the ID is the composite county FIPS and assessor parcel number.

curl

curl -H "Authorization: Bearer pz_your_key" \
  "https://api.propraven.com/v1/parcels/37183:0429966"

Python (requests)

import requests

resp = requests.get(
    "https://api.propraven.com/v1/parcels/37183:0429966",
    headers={"Authorization": "Bearer pz_your_key"}
)
parcel = resp.json()
print(parcel["address"], parcel["total_assessed_value"])

JavaScript (fetch)

const res = await fetch(
  "https://api.propraven.com/v1/parcels/37183:0429966",
  { headers: { Authorization: "Bearer pz_your_key" } }
);
const parcel = await res.json();
console.log(parcel.address, parcel.total_assessed_value);

Official SDKs: Python, TypeScript, Go

All three clients are generated from the same OpenAPI 3.1 document via Stainless, so method names mirror the REST paths (client.v1.parcels.retrieve is GET /api/v1/parcels/{id}) and a fix to the spec ships to every language at once. Each release carries a SLSA provenance attestation signed by GitHub Actions OIDC and recorded in the Sigstore transparency log; the source is public at jdw2111/propraven-python, jdw2111/propraven-typescript and jdw2111/propraven-go. Every client reads PROPRAVEN_API_KEY from the environment by default.

Python — propraven on PyPI · full guide

pip install propraven
from propraven import Propraven

client = Propraven()  # reads PROPRAVEN_API_KEY from env

# Single parcel
parcel = client.v1.parcels.retrieve("37183:0012345")
print(parcel.owner_name, parcel.assessed_value)

# Owner pierce
portfolio = client.v1.owners.retrieve_portfolio_summary("BLACKROCK FUND ADVISORS")

# Coverage stats
cov = client.v1.retrieve_coverage()
print(f"{cov.total_parcels:,} parcels across {cov.states_covered} states")

Python 3.9+. An AsyncPropraven client and propraven[pandas] / propraven[polars] / propraven[arrow] extras for DataFrame conversion are included.

TypeScript — @propraven/sdk on npm · full guide

npm install @propraven/sdk
import Propraven from "@propraven/sdk";

const client = new Propraven({
  apiKey: process.env.PROPRAVEN_API_KEY!,
});

// Single parcel
const parcel = await client.v1.parcels.retrieve("37183:0012345");
console.log(parcel.owner_name, parcel.assessed_value);

// Owner pierce
const portfolio = await client.v1.owners.retrievePortfolioSummary("BLACKROCK FUND ADVISORS");

// Coverage stats
const cov = await client.v1.retrieveCoverage();
console.log(`${cov.total_parcels.toLocaleString()} parcels across ${cov.states_covered} states`);

Node 18+, modern browsers, Deno, Cloudflare Workers, Bun. ESM + CJS dual export, with a verifyWebhook helper built on Web Crypto.

Go — github.com/jdw2111/propraven-go · full guide

go get github.com/jdw2111/propraven-go@latest
package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/jdw2111/propraven-go"
    "github.com/jdw2111/propraven-go/option"
)

func main() {
    client := propraven.NewClient(
        option.WithAPIKey(os.Getenv("PROPRAVEN_API_KEY")),
    )

    ctx := context.Background()

    parcel, err := client.V1.Parcels.Get(ctx, "06037:1234-567-890")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%+v\n", parcel.ParcelID)
}

Go 1.22+. The client retries 429s and idempotent 5xx by default; everything sits under client.V1.* to mirror the REST paths.

Rate limits and pricing

Plans are metered on lookups per month; that monthly cap is the enforced meter, and a per-key burst limit sits on top of it. The four tiers below are the same ladder the pricing page publishes.

TierLookupsPriceIncludes
Free1,000 / mo$0Full records in the web app, self-serve API keys. No card required.
Developer100,000 / mo$99/mo · 14-day free trialFull API, SDKs & webhooks, MCP connector, owner & sponsor graph.
Team1,000,000 / mo$1,000/moEverything in Developer, bulk export, priority support.
Data licenseUnmetered (bulk)CustomFull state or national tables via Snowflake, Databricks or Parquet. Annual license, invoiced.

Unauthenticated responses and every 429 carry the rate-limit headers X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset. Read your current-period consumption from GET /api/v1/account/usage. Sustained throughput above the Team cap, or whole-state and national tables, is the data license path rather than a bigger meter.

For AI agents: MCP server and x402 pay-per-call

The API has a second front door built for software that reasons rather than renders. The hosted Model Context Protocol server at mcp.propraven.com exposes 31 typed tools — parcel lookup, search and compare, owner pierce, hazard score, valuation estimate, permit and sales history, the deal finders, and the storefront pair — to Claude Desktop, Claude Code, Cursor, ChatGPT and any MCP-compatible client. The same pz_ key authenticates it as a bearer header; the claude.ai web connector uses OAuth instead. A local @propraven/mcp package on npm speaks stdio for latency-sensitive work. Setup for each client is on the MCP page, which is generated from the live tool registry.

{
  "mcpServers": {
    "propraven": {
      "url": "https://mcp.propraven.com/",
      "headers": { "Authorization": "Bearer pz_your_real_key_here" }
    }
  }
}

Agents that arrive with a wallet instead of an account use x402. The flow is discover → preview → pay: 2 tools (get_catalog and check_availability) are free and return the sealed field catalog with measured per-state coverage and the exact price of a specific parcel's dossier before anything is spent. Requesting the paid resource without payment returns HTTP 402 with the precise USDC-on-Base amount to sign; sign an EIP-3009 transferWithAuthorization, retry with the X-PAYMENT header, and the 200 carries the dossier plus an on-chain settlement receipt. A failed build is never charged. The dossier price is value-tiered and auditable — clamp($5 × V × R × F, $2, $20) — and lead feeds, owner reports, comp packs and risk scores follow the same 402 contract. The full walkthrough is on Connect your agent.

Data coverage behind the API

Every endpoint reads the same serving set the warehouse shares and the web app render: 191.3M parcels · 110.0M mapped at the 2026-08-30 epoch, 620 columns per parcel, 51 states (all 50 plus DC). The joined facts include 180M+ building permits, 10M+ title transfers, 27M+ resolved owners and 143M+ addresses; 110.0M distinct locations carry a coordinate the map can draw. Coverage is uneven by design of the sources — county assessors, recorders and permit offices publish different fields — so check GET /api/v1/coverage or the storefront catalog for the jurisdiction you care about rather than trusting a national average. The data page publishes live counts, the schema explorer and per-field fill rates; parcel data explains what a parcel record contains.

Representative endpoints

Twelve of the 46 paths in the spec, as a map of the territory. Paths are relative to https://api.propraven.com.

MethodPathDescriptionAuth
GET/api/v1/parcels/{id}Get parcel by IDAPI key
GET/api/v1/parcels/{id}/ownerGet parcel owner details and portfolioAPI key
GET/api/v1/parcels/{id}/permitsGet parcel permitsAPI key
GET/api/v1/parcels/{id}/deedsGet parcel deed historyAPI key
POST/api/v1/searchSearch parcels by bounds, filters, and sortingAPI key
GET/api/v1/search/exportExport search results as CSVAPI key
GET/api/v1/coverageGet coverage statisticsNone
GET/api/v1/deals/absenteeFind absentee ownersAPI key
GET/api/v1/owners/{name}/portfolioGet owner portfolio summaryAPI key
GET/api/v1/storefront/catalogMachine Storefront — sealed field catalogNone
GET/api/v1/parcels/{id}/reportParcel dossier (paid, provenance-first)Key or x402
GET/api/v1/account/usageCurrent-period usage and quotaAPI key

Webhooks

Polling is the wrong shape for change detection across 191.3M parcels, so the API pushes. Register an endpoint with POST /api/v1/webhooks and PropRaven delivers parcel.sold, parcel.permit_filed and parcel.owner_changed events signed with HMAC-SHA256 in the X-PropRaven-Signature header; each event carries a deterministic event_id for idempotency and the SDKs ship a constant-time verifier with a five-minute replay window. Payload schemas and delivery semantics are on the webhooks page.

Error Handling

Errors return a JSON object with an error field:

{
  "error": "Invalid API key"
}
StatusMeaning
400Bad request (missing or invalid parameters)
401Invalid or missing API key
402Payment required — the body is an x402 offer naming the exact amount
403API key is inactive or expired
404Resource not found
429Rate limit exceeded (check Retry-After header)
500Internal server error

OpenAPI Specification

The full OpenAPI specification is available at /openapi.json. Import it into Postman, Insomnia, or any OpenAPI-compatible tool, or point a ChatGPT Custom GPT Action at it with Bearer authentication.

Frequently asked questions

Is there a free tier for the property data API?
Yes. The Free plan is $0 and includes 1,000 lookups a month with self-serve API keys, and no card is required. The Developer plan ($99/mo, 100,000 lookups) has a 14-day free trial.
How do I authenticate requests?
Create a pz_ API key under Settings > API Keys and send it as a bearer token: Authorization: Bearer pz_your_key. The same key works for the REST API, the SDKs and the hosted MCP server.
Which SDKs are available?
Official clients for Python (pip install propraven), TypeScript (npm install @propraven/sdk) and Go (go get github.com/jdw2111/propraven-go), all generated from the same OpenAPI 3.1 spec and published with SLSA provenance.
Can an AI agent use the API without an account?
Yes. Paid resources such as the parcel dossier accept x402 pay-per-call: request without payment, receive an HTTP 402 naming the exact USDC-on-Base amount, sign it and retry. The catalog and availability preview are free and need no key.
How much data is behind the API?
191.3M parcels · 110.0M mapped at the 2026-08-30 epoch, 620 columns per parcel across 51 states, with 180M+ building permits, 10M+ title transfers and 27M+ resolved owners.