Skip to main content
GET
Read which data is available where
One call answers three questions. Is this place covered? For which datasets? How fresh is each one? The answer is one row per dataset for every loaded market. With a place, the answer is the markets that cover it and what each dataset gives it there. The route reads the in-memory table behind meta.coverage[] and runs no query. Zero credits, any key. The same facts, recorded from production, are the Coverage pages and coverage.json. This route is the live answer for the host you call.

Use it when

  • Before a data call. Ask if a point, a county or a ZIP is covered. Then you spend no metered call on a 422 outside_coverage. Pass lat and lng, county, zip or market. Pass at most one of the four.
  • To gate a screen per dataset. A partner map or the Investorlift app reads datasets.<key>.place_status for the place. It then shows or hides the listing, short-term rental or lender panel.
  • To say “planned” and not “not covered”. data.planned[] lists the markets under construction, as labelled intent.

The vocabulary

The keys of datasets are the datasets a market can lack. They are deeds, listings, agents, wholesale, auction, str, parcels, financing, permits, owner_profile, history, cash_sale, lenders and addresses. Each cell carries these fields. The history lake reads partial until a roster says how many ZIP codes a market has. A short-term rental jurisdiction that requires no licence reads not_applicable in the scope. It counts on neither side of the roll-up.

The place lookup

  • A point (lat, lng). The API applies the bounding-box-and-tolerance rule of every data route (bbox and point_tolerance_miles on the row), so the two never disagree.
  • A county (county=04021 or county=Pinal). The API matches it against the counties of the loaded markets. It then decides deeds and the lender registry at county grain. Pinal reads deeds served and lenders outside while the registry covers Maricopa alone.
  • A ZIP (zip=85142). The API resolves it to every county it touches, largest land share first (place.counties). The source is a committed copy of the public ZIP-to-county relationship file of the Census Bureau. The API then decides at county grain, and decides the history lake against its own ZIP set. A ZIP-universe market covers only its own ZIP codes.
  • A market code (market=phx). The API answers that row alone. An unknown code is outside, never 400.
A place nothing covers is 200 with data.markets: [] and place.status: outside, never 422. This is the one route that answers the question the data routes refuse. With a place, meta.coverage[] names the covering markets alone. A response outside every market carries an empty coverage list and no X-Dataset-Version header.

Planned markets

data.planned[] lists the markets Investorlift intends to serve and this host does not serve yet. Each row carries label_kind: "intent". Intent, not a commitment: a market is covered when it appears in data.markets[] and in meta.coverage[] on your responses. The Developer Agreement promises no refresh cadence and no continuity, and the list can change without notice. A code the host has loaded is never in this list.

Gotchas

  • The ETag comes from the dataset versions of the markets in the answer, not from the query. Cache by URL. Send If-None-Match for a 304 when nothing moved.
  • Two place groups at once (zip beside market, for example) are 400 geometry_conflict. So is lat without lng.
  • The concise MCP format of godmode_coverage caps the jurisdiction, issuer and ZIP lists at ten items. This route carries them whole.
GET /v1/dataset is the freshness probe: did the version move? This route answers what is covered where. Coverage and freshness explains meta.coverage[], the block both routes read. The Coverage pages state the answer as recorded from production.

Authorizations

Authorization
string
header
required

API key from the developer console (starts with zpka_). Create one at https://developers.investorlift.com/get-a-key.

Query Parameters

lat
number

With lng: the point to look up. The API decides the covering markets with the bounding-box-and-tolerance rule the data routes apply (meta.coverage[].bbox and point_tolerance_miles), so the two never disagree.

Required range: -90 <= x <= 90
lng
number

With lat: the point's longitude.

Required range: -180 <= x <= 180
county
string

A county to look up: a 5-digit FIPS ("04021") or a name ("Pinal", "Pinal County", any case). The API matches it against the counties of the loaded markets and the states of the public ZIP-to-county crosswalk. Not with lat, lng, zip or market.

Required string length: 1 - 64
zip
string

A ZIP to look up. The API resolves it to every county it touches through the public ZIP-to-county crosswalk, largest land share first, then decides at county grain. A ZIP-universe market covers only its own ZIP codes. Not with lat, lng, county or market.

Pattern: ^\d{5}$
market
string

A market code to look up: its row alone. An unknown code answers place.status outside with markets [], never 400. Not with lat, lng, county or zip.

Required string length: 1 - 16

Response

The coverage matrix, the place lookup and the planned markets.

The coverage matrix, the place lookup and the planned markets.

data
object
required

Which data is available where: the coverage matrix of every loaded market, the place lookup when you asked one, and the planned markets.

meta
object
required

Response metadata: when the API produced it, which markets it covers, and how fresh they are.