kind:
The flip test: the buyer held the parcel 30 to 365 days, and one of two price tests passes. The first test: both deeds
carry a price and the resale is 10 to 150% over the purchase price. The second test: the purchase deed records no
price, the usual Texas shape, and a registry investor made a priced resale. A resale under 30 days, or a chain resale
or round trip within 90, is
wholesale. A loss, a margin under 10%, a resale over 150%, a builder’s new home resold or
an iBuyer’s resale is other. About one flip in six has no investor id, because one clean flip by someone outside the
registry is still a flip.
Investors and ids. An investor is a group of names the registry believes are one operator. It gets a stable id like
inv_0a20a550f33b. When a data refresh merges or splits groups, it redirects or retires the old id. For a redirected
id, the API gives you the new one. For a retired id, the API answers a 410, so search by name again.
Store the id. Get the name again when you show it, or keep it only within the cache window.
Some buyers spread their purchases over several ids, a new LLC per deal. Every list row carries operator_id, the
id of the operation those ids belong to. You can collapse the rows that share it and contact that buyer once. It is
the busiest member’s id and can move after a refresh. Group by it within one response, and store the investor ids.
See Same buyer, cash right now.
Scale and the default list. Each investor has a scale: individual, small, mid, large or institutional.
Institutional means iBuyers (Opendoor, Offerpad), production homebuilders and bulk single-family landlords with 500 or
more houses. They dominate every neighbourhood by volume and are almost never the buyer for a wholesale deal, so the API
hides them by default. The API also hides public bodies: the county, the state land department, a housing authority.
Both come back when you ask for them: scale=...,institutional and include_public=true.
Recency means purchases, not sales. The API measures “Active” from the investor’s last purchase. A landlord who
sold ten houses last year and bought none is not an active buyer. The API counts every “days since” number from the
data’s end date (meta.coverage[].data_end), not from today, so it does not drift between refreshes.
Contact block. For each investor the API can return the people behind the entity and the mailing addresses that
appear on their deeds. It splits the names into given and surname, the way a skip-trace vendor wants them. It flags the
shared addresses (title companies, registered agents) as is_generic. The pre-assembled skip_trace_targets[] list
means “send these to BatchData in this order”. These fields are a partner feature: on api.investorlift.com every
response carries them as null with contact_redacted: true, and Authentication
says who does get them.
The rule behind it is simple: this host never serves contact fields. So member lists show only companies and trusts. A
person, a trust or an owner-occupant that bought with no investor id comes back with a null name. The API names a
registry investor by its registry name on every key, with display_name beside it to print. The registry name is
the deed spelling, and it can be a person’s when someone buys property in their own name.
Listings. Every hold deal row and every parcel carries listing, the MLS listing on the parcel as the feed last
saw it. The block carries the status (ACTIVE, PENDING, SOLD or OFF_MARKET), the asking price, the dates, days on
market and the listing agent. Every investor row carries listings: what they have on the market as of the feed’s
listings_data_end. It carries n_active, n_pending, the asking prices and last_listed_on.
A listing counts as the investor’s only when it started after they bought the parcel (owner_test PASSED). The
listing they bought under stays on the row with owner_test FAILED, and the API never counts it. The API measures
every listing window at meta.coverage[].listings_data_end, the feed’s own as-of date, later than data_end. Both
blocks are null in a market without published listing tables. Zeros mean the API checked and found nothing listed.
/v1/investors/{id}/deals?role=buyer&listing_status=on_market lists the holdings on the market in one page.
The listing_status values active, pending, sold, off_market and none filter the history by the record’s status. In a market
without the tables, the API answers 422 listings_unavailable. The agents’ names, phones and emails are contact fields,
a partner feature like every other. On this host they are null, and the API serves the agent’s id, brokerage and
identity basis. /v1/agents/{id} opens the profile behind an id, and /v1/agents/{id}/listings opens their history.
Both are in early access (Who is this listing agent?).
Investorlift listings as wholesale transactions. Since 0.4.0 every house listed on Investorlift is on file as a
wholesale transaction, whatever its status in the app. The county deeds judge it, and the rows you already read carry it.
A deal row whose deed closed a listing carries wholesale_listing. The block carries a one-word verdict,
verification, the detailed outcome, a name-free outcome_text, the listing company and the closing deed. The
verdict has four values:
CONFIRMED: a recorded deed closed it to a buyer.RETAIL: it closed to an owner-occupant or through the MLS.OPEN: no transfer yet.NONE: nothing within 400 days, or a transfer the rules do not tie to it.
wholesale_purchases: what they bought through Investorlift, as the deeds show. A parcel carries
wholesale_listings[]. source=investorlift on an investor’s deals and bought_on_investorlift=true on the deal list
filter by it. /v1/wholesale-listings lists the listings around a location with the verdict beside each. The
wholesaler routes profile the companies behind them. These routes are in early access
(Which Investorlift listings closed?).
The API names the buyer when it is a registry investor, whatever its kind, or an unregistered company. It never names
a person, a trust or an owner-occupant outside the registry. It never serves the listing’s status in the Investorlift
app, and it never serves the wholesaler’s own purchase price and spread. In a market without published
wholesale tables, all of it is null, and the wholesale routes and the two filters answer 422 wholesale_unavailable.
meta.coverage[].wholesale_as_of is null then.
Short-term rentals. Since 0.5.0 the API matches the cities’ own short-term rental licence and permit rolls to
parcels. The cities are in meta.coverage[].str.jurisdictions[], and Counties, cities and ZIP
codes lists them. Every parcel and every hold deal row inside a loaded city carries
short_term_rental, with these fields:
status: the status on the city’s roll,LICENSED,PENDINGorEXPIRED.NONEmeans the API serves the city and the parcel has no record.- The application, issue and expiry dates the roll carries.
permit_after_purchase: if the current owner got the licence after the purchase.owner_attributedwith itsattribution_basis. The basis is a date after the purchase, a name on the record, or the city’s regime that started after the purchase. It isASSUMEDwhen no fact decides it.business_use: attributed and not a person’s own home.prior_owner_permit: a licence that a former owner got, not the current owner.manager: the property-management company on the record, a business name that the API serves to every key.
meta.coverage[].str.jurisdictions lists every city the build knows and why the API does not serve the others. So the
explanation of a null is there, not on the parcel.
Every investor row carries str, the roll-up. It counts how many of their holdings are licensed business uses and how
many got a licence within 180 days of the purchase. It carries the share of their holds, the managers and the cities.
GET /v1/str-parcels, sold by contract, lists the licensed parcels around a location. str_status and
str_business_use filter the deal lists, and str_operator and str_holdings_min filter the deal and investor lists.
The business-use filter keeps hold rows whose licence is a business use attributed to the owner, the short-term rental
deal type.
One rule changes on a parcel that is not an investor’s hold. There the API treats the owner as one it can name, if the
city registered the owner as a business operator there. The record shows that by a date or a name, for example a
licence application after the purchase. redacted_reason is then null, but the name and address themselves stay null
on this host. A prior owner’s permit, an owner-occupied home with a casita permit and an assumed attribution keep the
licence facts and lose the identity. In a market without published short-term rental tables, the API answers 422
str_unavailable on the filters and the list route.
Foreclosure-auction buyers. Since 0.7.0 every investor row carries auction, with these fields:
n_auction_buys: how many houses they bought at a foreclosure auction. That is a trustee’s sale, or an Arizona sheriff’s sale, where the buyer is a third party, never the lender that bids its own loan.n_auction_buys_24m: how many in the last two years. The flagis_active_auction_buyerreads it.- The last sale day.
auction_resale_share: the share of those purchases that the buyer resold within a year.
n_reo_buys,
n_reo_buys_24m and is_active_reo_buyer. That buyer had weeks and an inspection, and possibly a loan.
The profile adds more detail. It lists the auction kinds the investor bought at: TRUSTEE_SALE, SHERIFF_SALE, and the
shown-but-not-counted HOA_TRUSTEE_SALE, TAX_SALE and TAX_LIEN_DEED. It names the platform that ran the sale where a
Texas servicer appointed one: Auction.com, ServiceLink or Xome. It gives the outcomes of the purchases at 12 months and
the median discount to the later resale. The outcomes are: resold, transferred, lost to a senior lender or held. Every
deal row carries bought_auction_kind when its purchase deed was such an auction purchase.
Three shared filters read the block: buys_at_auction=true, buys_reo=true, and the deal-level
bought_auction_kind=TRUSTEE_SALE. The first keeps the cash buyers of the last two years. In a market without
published counts (meta.coverage[].auction_counted false), the block is null on every investor. In that market
bought_auction_kind is null on every deal, by_channel.auction is null on the deals summary, and the three filters
answer 422 auction_unavailable. Filters has the rows.
Parcels, financing, permits and history. Since 0.8.0 you can search the parcel layer itself.
POST /v1/properties/search returns every parcel in a location that
matches the filter groups and the quicklists, with the blocks you ask for on each row.
The filter groups are owner, building, lot, sale, tax, listing, valuation, financing, liens, permits and history.
Beside it, three routes read one parcel in depth. financing gives the valuation, the open liens with their lenders
and rates, the recorded mortgages and the involuntary liens. permits gives the jurisdictions’ own permit rolls, with
the work tags and the dates, and never an applicant name. history with listing-history gives what changed week by
week, and every period on the market with its price path and outcome. GET /v1/markets/{market}/changes counts the
same events across a ZIP.
Read two limits before you build on them. The financing, lien and valuation numbers are a snapshot valued at
meta.coverage[].parcel.financing.as_of. Every response that carries one says so in meta.dated[] (see
dated data). The history routes answer only inside the ZIP codes the history lake
covers (meta.coverage[].parcel.history.zips). Elsewhere they answer 422 history_unavailable.
Lenders. Since 0.14.0 every lender of record on a recorded mortgage carries a stable id (len_ plus 12 hex). The
id is the same under every spelling the instruments use. GET /v1/lenders/search finds it from any of them.
GET /v1/lenders ranks the lenders of a market or of one ZIP, city or county over the 24 months to the slice date.
hard_money=true keeps the lenders who fund flippers.
GET /v1/lenders/{id} is the profile, one profile per market. It carries every spelling, the class and the hard-money
flag, and the loans counted once across the open liens and the recorded history. It carries the open book, the year and
month series against the market, and the product, term and property-type mix. It carries terms with how much of the
book carries them, geography, rankings and a written summary. GET /v1/lenders/{id}/loans lists every instrument.
Since 0.16.0 the recorded deeds decide if each loan financed a purchase (purpose). They tie the loan to the investor
deal it funded: deal on the loan row, financing on the deal row and the investor profile. They give the outcome of
the loan (outcome). The profile carries borrowers, who borrows, with churn as a lower bound. It carries
investor_lending: which registered investors borrow from it. It carries flips_financed, the flips it financed with
their margins, null under 20 resold flips.
GET /v1/lenders/{id}/borrowers lists the borrowers, one row per borrower key. The API serves a company’s name to
every key, and this host does not serve a person’s name.
Since 0.19.0 GET /v1/lenders/{id}/rankings places one lender in every ZIP, city, county or hex cell it lent in, or
month by month, over a chosen window. n_zips_ranked_first_24m on the profile is the headline: “#1 in N ZIPs”.
GET /v1/lenders/{id}/cells is its map. The list and the loans take a period and a point with a radius. The API
resolves that point and radius to hex cells, so the edge is a hex boundary.
The profile carries takebacks and is_auction_lender. The take-backs are the trustee’s deeds, sheriff’s deeds and
deeds in lieu that named the lender as grantee since 2016: deeds, never delinquency. A loan row says if a take-back
deed followed (foreclosed, outcome FORECLOSED). A borrower row names the other lenders it uses
(other_lenders[]). An Investorlift listing names the five lenders most active with investors in its ZIP
(lenders_active[]).
Three facts apply to every number. The registry comes from the dated financing slice, and meta.dated[] carries
the date. meta.coverage[].lenders.as_of is the slice date, and meta.coverage[].lenders.recordings_through is
the newest recording in it. The registry covers the counties in meta.coverage[].lenders.counties, which can be
narrower than the market, and Counties, cities and ZIP codes lists them. For a place outside
them, the API answers 422 outside_coverage. The recorded history captures about one open loan in five, so a
history count is a floor, and a bridge lender is the most undercounted.
Lender names are business records, and the API serves them to every key. A person-named lender has a profile only above
the person gate, and the API hides it unless include_persons=true. No lender carries a phone or an email. In a market
without the registry, the API answers 422 lenders_unavailable (Who is this lender?).