Skip to main content
GET
Rank the lenders of a market, a ZIP, city, county or geometry
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.
A page of lender ranking rows, most loans in the window first by default.

Use it when

The lender leaderboard: who funds deals here, which hard-money lenders are active in 85032, who writes construction loans in Scottsdale. For one lender’s standing, use its profile. Its rankings block places the lender overall, within its class and among hard-money lenders. For the loans behind a row, use GET /v1/lenders/{id}/loans.

How it works

  • One market at a time. The list ranks inside one market. If the API has several loaded markets and you name none, it answers 400 market_required and lists them.
  • One place at most. zip, city or county narrows the list to a place. The API reads the rows from a table pre-aggregated per lender and place. So the counts inside a ZIP are the lender’s loans there, not its market-wide book. The place must be inside the counties the registry covers, listed in meta.coverage[].lenders.counties and on Counties, cities and ZIP codes. Outside them the API answers 422 outside_coverage and names the covered counties, never an empty page.
  • Or around a point (since 0.19.0). A geometry ranks the lenders active in it instead: lat and lng with radius_miles, a bbox, or property_id. The API resolves the geometry to the H3 res-8 cells whose centre lies inside it, about a third of a square mile each. So its edge is a hex boundary, not the circle. The row’s in_geometry says how many cells the geometry became and how many of them carry the lender.
  • Under a geometry the API sums n, volume, the first-lien and product counts, n_purchase_money, n_investor and last_recorded_on over those cells. share, share_by_volume, n_unpriced, n_deals_financed and n_borrowers are null, not measured per geometry. Every sort orders the aggregate in memory.
  • A geometry beside zip, city or county is 400 validation_error (code geography_conflict). A point outside every loaded market’s tolerance is 422 outside_coverage. A point in a market other than market= is a 400 validation_error (code geometry_market).
  • meta.geometry echoes the shape you asked for, with the defaults filled. A property_id echoes as a radius of the default around the parcel. The cells the shape became are the row’s in_geometry. A zip or a city echoes as a place. The API does not echo a county. See the envelope.
  • The window. period (since 0.19.0) takes 24m (the default), 12m, all (every dated instrument), a calendar year YYYY or a month YYYY-MM. The default is the 24 months ending on as_of. The year runs from 2002 to the slice year, and the month is one of the 36 ending on the slice month.
  • Inside a place every window works. Market-wide only 24m or a month YYYY-MM works. The market-wide month rows are the profile’s by_month buckets, and the registry has no market-wide rows for 12m, all or a year. Around a point only 24m, 12m and all work, because the registry keeps the cells at those three.
  • Any other value is 400 validation_error, code period_not_served, and the message names the rule. Every windowed count on the row follows the window.
  • The count. n is every instrument of any kind recorded in the window, counted once across the open-lien and recorded-history tables. position=1 counts first liens alone. product= counts the named products alone. The two together count the first liens of those products. The registry pre-aggregates the per-product first-lien counts, so the API no longer refuses the pair.
  • purpose=purchase (since 0.16.0) counts the purchase-money instruments alone, those whose loan sits in the 45 days after a priced deed on the parcel. The API refuses it beside position or product, because the registry does not pre-aggregate that pair. min_n and the sort’s metric apply to n as selected. active_from applies to the lender’s newest recording in the place.
  • Investor lenders. investor_only=true (since 0.16.0) keeps the lenders whose window is half or more loans to registered investors, whatever the name says. The profile carries this as is_investor_lender. hard_money=true keeps the lenders that are hard money by name or, since the same release, by behaviour.
  • Who appears. The list hides persons (INDIVIDUAL, PRIVATE) and GOVERNMENT lenders unless you set include_persons=true or include_government=true. hard_money=true keeps the hard-money lenders and false keeps the rest. lender_class= narrows within the lenders that appear.
  • rank and share are the row’s, not the profile’s. The section Read a row says how the API measures each and why they differ from rankings.rank_24m. Since 0.19.0 the row also carries share_by_volume, the lender’s volume over every lender’s in the same window and place. It also carries n_borrowers, its borrowers in the window, market-wide or inside the place. GET /v1/lenders/{id}/rankings is the other way round: it lists every place one lender ranks in.
  • Sorts. loans_desc (the default), volume_desc, open_liens_desc, open_balance_desc, last_recorded_desc and, since 0.16.0, purchase_desc. That sort puts the most purchase-money loans in the window first, and the lenders without one last. The open-lien and open-balance sorts order by the lender’s market-wide book even inside a place.

Gotchas

  • A GOVERNMENT row counts claims and insurance, not originations. HUD and the VA appear as lenders on the partial-claim seconds and insurance claims recorded under the agency’s name.
  • A bridge lender ranks below its activity. The history captures about one open loan in five, and it counts a short-term loan only while the loan is open. The bias is the same on every row, so compare hard-money lenders with each other.
  • A period other than 24m, a geometry and share_by_volume read the place rankings. On a registry built before them, the API answers 422 lenders_unavailable and names the parameter. On such a registry share_by_volume is null on every row, and n_borrowers inside a place is null too. Market-wide it reads the borrower match, and the API serves it from 0.16.0.
  • purpose, investor_only and sort=purchase_desc read the deed link. On a registry built before it, the API answers 422 lenders_unavailable. The counts they read are null on every row there.
  • Every row is dated (meta.dated[]). The as_of is the slice date in meta.coverage[].lenders.as_of. With require_current=true the API answers 422 dated_refused. The API measures recency (last_recorded_on, active_from) against meta.coverage[].lenders.recordings_through, fourteen days before as_of.
  • For a market with no published lender registry, the API answers 422 lenders_unavailable. A cursor from another query or an older dataset is 400 invalid_cursor.
Who is this lender? ends with the hard-money lenders active in one ZIP and the ZIPs one lender leads. Rank one lender by place is this list inverted: every place one lender ranks in.

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

market
string

Market code, for example phx. The loaded markets are in meta.coverage[]. The list ranks inside one market. When meta.coverage[] lists more than one market and you send none, the API answers 400 market_required and lists them in extra.markets. If the market has no published lender registry, the API answers 422 lenders_unavailable.

Required string length: 1 - 16
period
string
default:24m

The window the counts cover: 24m, the default, is the 24 months ending on the slice date. 12m is the 12 months ending on it, all is every dated instrument, and a calendar year YYYY runs from 2002 to the slice year. A month YYYY-MM is one of the 36 ending on the slice month, and any other value answers 400 validation_error with code period_not_served. Market-wide the list serves 24m and a month, and the other periods need a ZIP, city, county or geometry. A geometry serves the three windows alone.

Pattern: ^(12m|24m|all|\d{4}|\d{4}-(0[1-9]|1[0-2]))$
lat
number

Point latitude (with lng). With radius_miles it is the geometry. The API resolves the circle to the H3 res-8 cells whose centre lies inside it, so its edge is a hex boundary. Do not send it with zip, city or county (400 geography_conflict). On a registry built before the place rankings, the API answers 422 lenders_unavailable.

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

Point longitude (with lat).

Required range: -180 <= x <= 180
radius_miles
number

Search radius in miles around the point or around the centre of the property_id parcel, 0.25 to 20 (default 2). Not allowed with bbox.

Required range: 0.25 <= x <= 20
bbox
string

Viewport as west,south,east,north (WGS84 degrees). West must be less than east, south less than north, and the diagonal at most 40 mi. It must intersect a loaded market's coverage bbox (422 outside_coverage otherwise). It can carry lat + lng (without radius_miles) as the reference point for distances and sort=distance.

property_id
string

Parcel geometry: search around the centre of that parcel, with radius_miles. Not allowed with lat, lng or bbox.

Pattern: ^prop_[0-9a-f]{32}$
lender_class
enum<string>[]

Keep only lenders of these classes (comma list or repeated key): BANK, NONBANK, PRIVATE, INDIVIDUAL, GOVERNMENT. It does not lift the two defaults below: INDIVIDUAL and PRIVATE still need include_persons=true, and GOVERNMENT needs include_government=true. For the hard-money sense of private lender, use hard_money=true, not lender_class=PRIVATE.

Minimum array length: 1

How the lender name reads. BANK: a bank, credit union or thrift. NONBANK: a mortgage company or other lending business. PRIVATE: a trust, a seller carry-back or another private party, not the hard-money sense of private lender, which the Lender object carries as is_hard_money. INDIVIDUAL: a person's name. GOVERNMENT: an agency or a public body.

Available options:
BANK,
NONBANK,
PRIVATE,
INDIVIDUAL,
GOVERNMENT
hard_money
enum<string>

true keeps only hard-money lenders (is_hard_money true). false keeps only the rest. Default: every lender. The registry flags a hard-money lender by name or brand, or by behaviour in a market with the deed link.

Available options:
true,
false
include_persons
enum<string>
default:false

true includes lenders whose class reads INDIVIDUAL or PRIVATE: a person's name, a trust, a seller carry-back. Default false hides them, the way investor lists hide institutional investors.

Available options:
true,
false
include_government
enum<string>
default:false

true includes GOVERNMENT lenders: HUD, the VA, a housing authority. Their counts are insurance claims and partial-claim seconds recorded under the agency's name, not originations. Default false hides them.

Available options:
true,
false
position
integer

1 counts first liens only: the instruments whose open lien position is 1 (n_first_lien). The API serves no other value. With product[] the row's n is the first liens of the named products, from precomputed counts.

Required range: 1 <= x <= 1
product
enum<string>[]

Count only instruments of these products (comma list or repeated key): CONSTRUCTION, HELOC, OTHER. The row's n is the sum of the named counts. With position=1 it is their first liens alone. The row's share is null (no per-product denominator).

Minimum array length: 1

What the file says the loan is, read from its flags and loan type and never from the label. CONSTRUCTION: the construction flag or a "Building or Construction Loan" type. HELOC: the credit-line flag or a "Credit Line (Revolving)" type. OTHER: everything else, that is a purchase-money or refinance mortgage of any kind.

Available options:
CONSTRUCTION,
HELOC,
OTHER
purpose
enum<string>

purchase counts only the window's purchase-money instruments: purpose PURCHASE by the deed link. The deed link sets PURCHASE when it finds a priced deed on the parcel in the 45 days up to the recording. The row's n is n_purchase_money and share is null (no purchase-money denominator). The API serves no other value. Do not send it with position or product (400 validation_error, code not_precomputed). While the market's registry predates the deed link, the API answers 422 lenders_unavailable (meta.coverage[].lenders.purchase_measured false).

Available options:
purchase
investor_only
enum<string>

true keeps only investor lenders by behaviour (is_investor_lender true). false keeps only the rest. Default: every lender. The flag is true when half or more of the window's instruments go to registered investors and the window holds 20 or more. While the market's registry predates the borrower match, the API answers 422 lenders_unavailable.

Available options:
true,
false
zip
string

Rank inside one 5-digit ZIP, from the pre-aggregated geography table. For a ZIP outside the covered counties (meta.coverage[].lenders.counties), the API answers 422 outside_coverage. Send at most one of zip, city or county.

Pattern: ^\d{5}$
city
string

Rank inside one city, as the parcel table writes it ("SCOTTSDALE"). Case does not matter. For a city outside the covered counties, the API answers 422 outside_coverage. Send at most one of zip, city or county.

Required string length: 1 - 100
county
string

Rank inside one county, a 5-digit FIPS such as 04013. For a county outside meta.coverage[].lenders.counties, the API answers 422 outside_coverage. Send at most one of zip, city or county.

Pattern: ^\d{5}$
sort
enum<string>
default:loans_desc

Row order of the lender list: loans_desc, the default, puts the most loans in the window first. With volume_desc, the largest loan total in the window comes first, and with open_liens_desc the most open lien positions at the slice date. With open_balance_desc, the largest open balance comes first. With last_recorded_desc, the newest recording comes first and undated lenders last. With purchase_desc, the most purchase-money loans in the window by the deed link come first, and lenders without a deed link last.

Available options:
loans_desc,
volume_desc,
open_liens_desc,
open_balance_desc,
last_recorded_desc,
purchase_desc
active_from
string

Keep only lenders whose newest recording (last_recorded_on) is on or after this date, YYYY-MM-DD. If you name a geography, the API reads the newest recording inside it.

min_n
integer
default:1

Keep only lenders whose n is at least this, default 1. The n is the count that position or product selects. The API never lists a lender with nothing in the window.

Required range: 1 <= x <= 9007199254740991
limit
integer
default:100

Page size, 1-500 (default 100).

Required range: 1 <= x <= 500
cursor
string

Opaque cursor from page.next_cursor of the previous page. A change of query, sort, weights or data version invalidates it (400 invalid_cursor). Then restart from page 1.

Required string length: 1 - 4096
require_current
enum<string>
default:false

true refuses the request with 422 dated_refused while the registry's source, the financing slice, is a dated snapshot. The default false serves it, and meta.dated[] carries the lenders and financing blocks.

Available options:
true,
false

Response

The ranked lenders, one page in the requested sort.

The ranked lenders, one page in the requested sort.

data
object[]
required

The rows of this page.

page
object
required

Pagination: the page size, the rows returned and the cursor for the next page. Paged lists carry no total. The summary block does.

meta
object
required

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