Skip to main content
Early access: while the developer tier is in beta, the API serves this route to Investorlift’s team and trusted partners. Investorlift will restrict the route further before it opens to every key.
Every house listed on Investorlift is on file as one wholesale listing, with the id wl_ plus 32 hex characters. The outcome the row reports comes from the county deeds, never from the listing’s status in the app. The API does not read that status and does not serve it.

The verdict

verification is the one-word answer: outcome is the detail behind the verdict: ASSIGNED, DOUBLE_CLOSED, LISTER_HELD_THEN_SOLD, SOLD_TO_OWNER_OCCUPANT, NO_TRANSFER_400, PENDING and the rest. outcome_text is a name-free sentence you can show.

Show the uncertainty

confidence, time_fit, deed.chain_certain, lister_attribution (“listed by n companies”) and retail_signals[] say how certain the match between the listing and the deed is. Show them as text, never as a colour alone. A confirmed row with low confidence is a different claim from a confirmed row with high confidence, and a colour cannot carry that.

Who is named

The buyer rule is the deal rule. buyer carries an id and a name when the grantee is a registry investor, whatever its kind. It carries a name alone for a company not yet in the registry. It carries neither for a person, a trust or an owner-occupant outside the registry. tier says which case you are in. Since 0.31.0 buyer.display_name and intermediate.display_name carry the name to print beside name. They follow the investor object’s rule: given-first for a cleanly parsed person, equal to name otherwise. Each is null exactly when name is null. The row always names the wholesaler: it is a business.
The wholesaler’s own contract price and spread never leave the pipeline. They are not in any response, on any key.

Join back to the deeds

registry_deal_id is the Deal that the API serves the closing deed as. So a listing and its deed are two views of one event. The default primary_only=true lists each closing deed once when several listings of the parcel can claim it.

Who lends here

lenders_active[] (since 0.19.0) names the five lenders with the most loans to registered investors in the listing’s ZIP. The window is the 24 months to the lender registry’s slice date. The sort is n_investor first, then n, then id. The API reads the array from the registry’s ZIP rankings at request time. It is the marketplace’s lender panel: who funds this kind of deal here. Each entry is a stub (id, name, lender_class, is_hard_money) with six more fields. n counts every instrument the lender recorded in the ZIP over the window. n_investor and n_purchase_money follow. n_purchase_money is null where the market has no deed link. share is the lender’s share of every lender’s instruments in the ZIP. as_of and dated complete the entry. The array is empty when the ZIP has no investor lending in the window. It is null on a hidden-address row. It is also null in a market without the lender registry or its borrower match. Rows served from a registry built before that match carry null too. While the row carries the block, meta.dated[] names lenders beside financing, because the registry is a snapshot at its own slice date. The block is not in the listings CSV. The concise MCP row of godmode_wholesale_listings leaves it to the detailed format.

Availability

A market without published Investorlift wholesale tables answers 422 wholesale_unavailable on the six wholesale routes and the two filters. It serves every wholesale block null. meta.coverage[].wholesale_as_of is the date of the export, and tells you in advance.

One Investorlift listing as a wholesale transaction: what the company listed, what the county deeds record for it, and who bought it. The verdict is verification. outcome carries the detail, and outcome_text carries the sentence.

id
string
required

Investorlift listing id: wl_ followed by 32 hex characters, for example wl_9f2c1d0e8b7a6c5d4e3f2a1b0c9d8e7f. The id is stable per Investorlift listing and the same in every market. It is the key to GET /v1/wholesale-listings/{id}. The prefix is part of the id.

Pattern: ^wl_[0-9a-f]{32}$
market
string
required

Market code the listing belongs to, for example phx. The loaded markets are in meta.coverage[].

source_listing_id
integer
required

The listing's id in the Investorlift app, for example 34905: the join key back to the app and to the feedback file.

Required range: -9007199254740991 <= x <= 9007199254740991
property
object | null
required

The parcel the API matched the listing to: the key to GET /v1/properties/{property_id} and the address to show. Null on a hidden-address listing, where the company hid the address on its own site, with no closing deed by the deed data_end. Such a row never matches a geometry, is absent from the parcel's wholesale_listings[], and is reachable under its wholesaler only.

distance_miles
number | null
required

Miles from the reference point, rounded to 2 decimals. The reference point is lat + lng, or the centre of the property_id parcel. Null when the request had no reference point, and on a hidden-address row.

wholesaler
object
required

The company that listed the house on Investorlift, with its brands. The API always serves it, as a business name.

listing
object
required

What the listing said on Investorlift: dates and prices as the company published them. The API never serves the company's own purchase price.

outcome
enum<string>
required

What the county deeds record for the listing, in detail. The one-word verdict is verification. ASSIGNED: one deed from the homeowner to the buyer, and the listing company is not on title, so a contract assignment. DOUBLE_CLOSED: two chained deeds 0 to 14 days apart, with the company or its buyer in the middle. LISTER_HELD_THEN_SOLD: the company took title and resold within 90 days. LISTER_SOLD_FROM_INVENTORY: the company already owned the house and sold it. SOLD_OFF_MARKET_GRANTOR: one deed from a seller who is neither the homeowner of record nor the company, so an unrecorded step came before it. SOLD_TO_OWNER_OCCUPANT: the buyer moved in, so not an investor sale. FAILED_THEN_RETAIL_MLS: the homeowner sold on the MLS instead. DISTRESSED_TRANSFER: a sheriff's, trustee's or REO deed. LATE_TRANSFER: a deed 180 to 400 days after the listing that nothing ties to it. NO_TRANSFER_400: no deed within 400 days. NO_DEED_120: no deed by the deed data end, 120 to 400 days after the listing, so provisional. PENDING: the company listed the house fewer than 120 days before the deed data end, and no deed exists yet. SUPERSEDED: another Investorlift listing of the same parcel holds the credit for the deed. AMBIGUOUS_DEEDS: two or more unrelated sales that the rules cannot order.

Available options:
ASSIGNED,
DOUBLE_CLOSED,
LISTER_HELD_THEN_SOLD,
LISTER_SOLD_FROM_INVENTORY,
SOLD_OFF_MARKET_GRANTOR,
SOLD_TO_OWNER_OCCUPANT,
FAILED_THEN_RETAIL_MLS,
DISTRESSED_TRANSFER,
LATE_TRANSFER,
NO_TRANSFER_400,
NO_DEED_120,
PENDING,
SUPERSEDED,
AMBIGUOUS_DEEDS
verification
enum<string>
required

The API derives the one-word verdict of the deeds on the listing from outcome alone, and the Investorlift status plays no part. CONFIRMED: a recorded deed closed it to a buyer, so a verified wholesale transaction. RETAIL: it closed, but to an owner-occupant or through the MLS, so not an investor sale. OPEN: the deeds record no transfer yet, up to the deed data_end. NONE: no transfer within 400 days, a distressed deed, or a transfer the rules cannot tie to this listing. NONE also when the credit went to another listing of the parcel.

Available options:
CONFIRMED,
RETAIL,
OPEN,
NONE
outcome_text
string
required

One name-free sentence that says what the deeds show, ready to display. For example "closed 2024-06-10: bought by a registered investor per the recorded deed" or "listed 2024-03-02; no recorded transfer yet". Add the buyer's name from buyer.name when that field is not null.

time_fit
boolean | null
required

True when the closing deed sits inside the expected window of the listing. The window runs from 30 days before to 120 days after publication, or from 45 days before to 120 days after the accepted offer. False when it closed later or earlier than that, and the API then caps confidence at MEDIUM. Null without a closing deed.

closed_before_publish
boolean | null
required

True when the county recorded the closing deed before the company published the listing: the company's own acquisition, or a listing published after closing. Null without a closing deed.

confidence
enum<string>
required

How sure the match between the listing and the deed is, to show as text beside the verdict. HIGH: the parcel matched exactly, and the deed sits inside the expected window with a corroborator. A corroborator is a price match, the company on title, the accepted offer's buyer on the deed, or a chained pair. MEDIUM: a deed inside the window without a corroborator, an off-market grantor, or a late or uncertain-order deed. LOW: a fuzzy parcel match or a guessed unit. NONE: below the floor, so the API serves the row without a buyer.

Available options:
HIGH,
MEDIUM,
LOW,
NONE
buyer
object
required

Who bought the house per the recorded closing deed. The API names the buyer when the deed names a registry investor, whatever its kind, or an unregistered company. The API describes a person, a trust or an owner-occupant that is not itself a registry investor by tier alone, never by name.

intermediate
object
required

The party that held title between the homeowner and the end buyer on a chained pair of deeds, when one exists.

deed
object
required

The recorded deed that closed the listing: when, in what shape, and for how much.

registry_deal_id
string | null
required

The deal row the API serves the closing deed as, deal_ followed by 32 hex characters: the key to GET /v1/deals/{id}. That row's wholesale_listing block points back here. Null when the deed is not a served deal: a household buyer with no investor id, or no closing deed.

lenders_active
object[] | null
required

The five lenders with the most investor loans in the listing's ZIP in the 24 months to the lender registry's slice date. They show who funds this deal kind here. The order is n_investor desc, then n, then id, from the registry's ZIP rankings. Empty when the ZIP has no investor lending. Null on a hidden-address row, and in a market without the lender registry or its borrower match. Also null on rows of a registry built before phase 3.

lister_attribution
string
required

Who gets the credit for the closing deed when several Investorlift listings of the same parcel can claim it. PRIMARY: this listing, because its accepted offer's buyer is on the deed, its company is on title, or it sat closest before the deed. SHARED(n): n companies listed the house and nothing tells them apart, so "listed by n companies", and none carries "sold by". UNCERTAIN: a retail, distressed or ambiguous outcome. NONE: no closing deed. Wholesaler and investor counts use PRIMARY rows only.

lister_on_title
enum<string>
required

How the listing company, or a partner entity of its account, appears on the deeds. NONE: an assignment, so the company never held title. INTERMEDIATE: it bought and resold, the middle of a double close. GRANTOR: it sold the house on the closing deed. PRIOR_OWNER: it already owned the house before the listing.

Available options:
NONE,
INTERMEDIATE,
GRANTOR,
PRIOR_OWNER
lister_on_title_role
enum<string> | null
required

Which entity of the listing company's account is on title. OWN: the company's own entity, its title or a brand. PARTNER: a joint-venture partner entity listed under the account. Null when lister_on_title is NONE.

Available options:
OWN,
PARTNER
buyer_fate
enum<string> | null
required

What the buyer did with the house after the closing deed, as of the deed data_end, or null without a closing deed. HELD: the buyer still owns it at the deed data_end. RESALE_15_90: the buyer resold within 90 days, and so behaved like a wholesaler. RESALE_91_365: the buyer resold within a year, a flip. RESALE_366P: the buyer resold after more than a year. MLS_LISTED: the house is on the market in the MLS feed, as of the market's listings_data_end.

Available options:
HELD,
RESALE_15_90,
RESALE_91_365,
RESALE_366P,
MLS_LISTED
offer_buyer_match
enum<string> | null
required

How the buyer named on the accepted Investorlift offer compares with the buyer on the deed, or null without a closing deed. EXACT: the same name. TOKEN: the same words in another order. DIFFERENT: the offer named a different party than the deed, for example a disposition agent who bid for a client. Show DIFFERENT as text: the API never names the offer party. UNNAMED: the offer carried no buyer name, or the listing had no accepted offer.

Available options:
EXACT,
TOKEN,
DIFFERENT,
UNNAMED
retail_signals
string[]
required

The retail tests that fired on the closing deed. Empty when none did. Two signals make a RETAIL verdict. Show them as text beside the verdict, never as a colour alone.

One signal code. For example R1 says the buyer's mailing address is the house, and R2 says the homeowner listed on the MLS.

n_other_listings
integer
required

Other Investorlift listings of the same parcel, at any time: n_listings_on_parcel minus 1. 0 when this is the only one.

Required range: -9007199254740991 <= x <= 9007199254740991
n_listings_on_parcel
integer
required

Every Investorlift listing of the parcel, this one included (n_other_listings + 1).

Required range: -9007199254740991 <= x <= 9007199254740991
superseded_by_id
string | null
required

On a SUPERSEDED row, the listing of the same parcel that holds the credit for the deed. Null otherwise.

Pattern: ^wl_[0-9a-f]{32}$
data_end
string
required

The deed data end date, YYYY-MM-DD, the same as meta.coverage[].data_end. The API measures every window on this row against it.

as_of
string
required

The date of the Investorlift export behind this row, YYYY-MM-DD, the same as meta.coverage[].wholesale_as_of.