Texas Parcel APISanova Services
OpenAPI spec Get API Key →

Texas Parcel API

Look up any Texas property by coordinate, address, APN, owner, or acreage — 14.3 million parcels with owners, valuations, and GeoJSON boundaries, straight from the authoritative state parcel layer.

14,347,648parcels
253counties
27 + geoattributes / parcel
EPSG:4326WGS84 coordinates

The Texas Parcel API turns the statewide TxGIO StratMap 2025 parcel layer into a fast, queryable REST service. Every lookup returns the full assessor record: owner, mailing & situs address, land-use codes, land / improvement / market valuations, legal description, FIPS, tax year — and the parcel boundary polygon as GeoJSON on request. Served from PostGIS with spatial (GiST), trigram, and B-tree indexes, so point-in-polygon and owner searches typically return in well under a second.

Authentication

The API is distributed through RapidAPI. Subscribe to a plan to get your personal API key, then send it on every request using these two headers:

HeaderValue
X-RapidAPI-KeyYour personal key from the RapidAPI dashboard
X-RapidAPI-Hosttexas-parcels-api.p.rapidapi.com

Base URL

https://texas-parcels-api.p.rapidapi.com
RapidAPI verifies your key, meters usage against your plan, and securely forwards the request to the origin. Keep your X-RapidAPI-Key private — treat it like a password.

Quickstart

Find the parcel under a point in downtown Austin:

curl --request GET \
  --url 'https://texas-parcels-api.p.rapidapi.com/parcels/by-point?lat=30.2672&lon=-97.7431' \
  --header 'X-RapidAPI-Key: YOUR_KEY' \
  --header 'X-RapidAPI-Host: texas-parcels-api.p.rapidapi.com'

Example response (truncated)

[
  {
    "id": 68992,
    "apn": "200164",
    "owner_name": "TEXAS PUBLIC FINANCE AUTHORITY",
    "acreage": 21.93534558,
    "market_value": 0.0,
    "situs_state": "TX",
    "county": "TRAVIS",
    "geometry": null
  }
]

Typical workflow

You rarely call the single-parcel endpoint directly with an ID. Instead, you discover parcels with a search endpoint, then optionally hydrate a specific result for full detail and geometry:

1. Search — call by-address, by-point, by-apn, by-owner, by-county, or by-acreage with something you know.
2. Read the id — every parcel in the response includes its id.
3. Hydrate (optional) — call GET /parcels/{id}?include_geometry=true for the full record plus boundary polygon.

Set include_geometry=true on any lookup to get the GeoJSON MultiPolygon boundary inline — handy for Leaflet, Mapbox, QGIS, or Turf.

Endpoints

All /parcels/* endpoints require your RapidAPI key. include_geometry defaults to false on lookups and true on the single-parcel endpoint.

GET/healthno auth

Service health probe. No parameters.

GET /health  →  {"status":"ok"}
GET/parcels/by-point

Find the parcel at a latitude/longitude (point-in-polygon, up to 5 matches).

ParamTypeRequiredDefaultNotes
latfloatyesLatitude, WGS84
lonfloatyesLongitude, WGS84
include_geometryboolnofalseReturn GeoJSON boundary
GET /parcels/by-point?lat=30.2672&lon=-97.7431
GET/parcels/by-address

Find a parcel by street address. Geocodes the address (U.S. Census) and returns the nearest parcels within ~100 m, ordered by proximity (up to 5). No separate geocoder needed.

ParamTypeRequiredDefaultNotes
addressstringyesAny U.S. street address
include_geometryboolnofalseReturn GeoJSON boundary
GET /parcels/by-address?address=100 Congress Ave, Austin, TX 78701
GET/parcels/by-apn

Look up a parcel by county + APN / parcel number (case-insensitive exact match).

ParamTypeRequiredDefaultNotes
countystringyesTexas county name
apnstringyesParcel ID / APN
include_geometryboolnofalseReturn GeoJSON boundary
GET /parcels/by-apn?county=Travis&apn=200164
GET/parcels/by-owner

Find all parcels owned by a person or entity (case-insensitive substring match, 25 results per page).

ParamTypeRequiredDefaultNotes
namestringyesOwner name (substring)
pageintno11-indexed, 25/page
include_geometryboolnofalseReturn GeoJSON boundary
GET /parcels/by-owner?name=CITY OF AUSTIN&page=1
GET/parcels/by-county

List every parcel in a county (50 results per page, geometry omitted for speed).

ParamTypeRequiredDefaultNotes
countystringyesTexas county name
pageintno11-indexed, 50/page
GET /parcels/by-county?county=Travis&page=1
GET/parcels/by-acreage

Find parcels in a county within an acreage range (50 per page, sorted largest first; geometry omitted).

ParamTypeRequiredDefaultNotes
countystringyesTexas county name
minfloatno0Minimum acres (inclusive)
maxfloatno1e9Maximum acres (inclusive)
pageintno11-indexed, 50/page
GET /parcels/by-acreage?county=Travis&min=10&max=100&page=1
GET/parcels/{id}

Get one parcel's full record, including geometry by default. The id comes from the response of any search endpoint above — it is an internal handle, not something an end user types.

ParamTypeRequiredDefaultNotes
idintyes (path)Internal parcel ID from a search result
include_geometryboolnotrueGeoJSON boundary included unless false
GET /parcels/68992

Response schema

Every endpoint returns a Parcel object (or an array of them). geometry is null unless include_geometry=true (or on GET /parcels/{id}, where it is included by default).

FieldTypeExample
idint68992
apnstring"200164"
geo_idstring"210040114"
owner_namestring"SMITH, JOHN"
name_carestring"c/o Jane Doe"
legal_descstring"LOT 1 BLK A SUNSET ADDN"
legal_areafloat5.25
legal_area_unitstring"Acres"
acreagefloat5.25
state_land_usestring"A1"
local_land_usestring"101"
land_valuefloat50000.0
improvement_valuefloat150000.0
market_valuefloat200000.0
situs_addressstring"100 Congress Ave"
situs_citystring"Austin"
situs_statestring"TX"
situs_zipstring"78701"
mail_addressstring"PO Box 456"
mail_citystring"Austin"
mail_statestring"TX"
mail_zipstring"78767"
countystring"Travis"
fipsstring"48453"
sourcestring"StratMap 2025"
date_acquiredstring"2020-01-15"
tax_yearint2024
year_builtstring"1995"
geometryGeoJSON | null{"type":"MultiPolygon",…}

Errors

StatusMeaning
200Success — parcel object or array returned.
401Missing or invalid RapidAPI key.
404No parcel found (e.g. unknown ID or unmatched address).
422Invalid parameter (e.g. non-numeric id, missing required query param).
429Rate limit exceeded for your plan.
Searches that match nothing return an empty array [] with status 200 — only the single-parcel GET /parcels/{id} returns 404 when an ID doesn't exist.