The data is big on purpose: every loan officer, agent, company, loan, and parcel on record. Filters are how you turn it into an answer. They stack, they compose with AND, OR, and NOT, and you can count the matches for free before you fetch a single row.
One grammar, every field
A filter key accepts the same value forms wherever it appears, so a range on volume looks like a range on avmValue or loanRecordedDate.
| You want | Write | Notes |
|---|---|---|
| Exactly this | "state": "TX" | Case-insensitive for codes and enums |
| Any of these | "state": ["TX", "OK", "AR"] | A list is OR |
| A range | "units": { "gte": 24, "lt": 100 } | gt, gte, lt, lte in any combination |
| A date range | "loanRecordedDate": { "gte": "2024", "lte": "2025-06" } | Partial dates expand to the whole period. { "gte": "2024" } means on or after Jan 1, 2024 |
| Fuzzy text | "office": { "match": "compass" } | For names and free text |
| A flag | "hasPhone": true | Booleans are a guarantee when true |
| Keep unknowns | "beds": { "lte": 2, "includeNulls": true } | Ranges drop records with no value unless you ask |
Every key inside flatFilters is ANDed. Add "mode": "or" to OR them instead.
Watch the units. equityPct is a fraction, so 50% equity is { "gte": 0.5 }. salePropensity, loanLtv, and the Community Lending shares are whole percents, so { "gte": 80 }. Each field’s reference entry says which.
Geography that means what you mean
The same word can mean three different places for a loan officer: where they produce, where their office is, and where they’re licensed. The filters keep them apart.
- Where they produce:
state,city,county,zip, andmsaon loan officers match the markets they closed loans in during the period. A loan officer in Round Rock who lends into Austin matches"msa": "12420". - Where the office is:
officeState,officeCity,officeZip, orofficeGeoPointfor a radius around a point or around another loan officer’s office. - Agents match on any location signal by default. Set
"locationSource": "production"to use only where they close, or"office"for their current brokerage. - Properties take a 5-digit FIPS in
county, a 5-digitzip, orgeoPointwith{ "lat", "lon", "radius": "15mi" }. - Names resolve.
"county": "Travis"with"state": "TX"works, and the response reports how each place resolved inlocationNormalizations, so an ambiguous name never silently matches nothing.
Scoped to one market
A plain volume filter asks about the loan officer’s whole book. footprint asks about one market inside it:
{
"footprint": { "city": "Orlando", "state": "FL", "volume": { "gte": 15000000 } },
"period": "last12Months"
}
That’s “$15M originated in Orlando”, not “$15M somewhere and one loan in Orlando”. Put a product inside the footprint for “$1M of FHA in Orlando”. Sort by scopedVolume to rank by production inside the market you named.
Production, not just presence
Beyond geography, the filters that separate a real prospect from a name:
- Volume and units for the period:
"volume": { "gte": 50000000 }. - Product mix as a share of their book:
"productMix": [{ "product": "fha", "minShare": 30 }]. Pair it with aunitsfloor so two loans don’t read as a specialty. - Transaction mix:
"transactionMix": [{ "transactionType": "purchase", "minShare": 60 }]. - Momentum:
peakMonthVolumefor “had a $10M month”,lastTransactionDatefor “closed something since July”. - Career:
yearsInIndustry,licensedSinceDatefor newly licensed,timeAtCompanyMonthsfor recent movers,stateCountandmarketCountfor how spread out they are. - Contactability:
hasPhone,hasEmail,hasSocial.
Combine with AND, OR, and NOT
When flat filters aren’t enough, advancedFilters is a boolean tree over the same fields:
{
"flatFilters": { "state": "TX", "units": { "gte": 24 } },
"advancedFilters": {
"type": "and",
"children": [
{
"type": "or",
"children": [
{ "type": "filter", "field": "fhaPct", "op": "gte", "value": 30 },
{ "type": "filter", "field": "vaPct", "op": "gte", "value": 30 }
]
},
{ "type": "not", "child": { "type": "filter", "field": "companyCategory", "op": "eq", "value": "BANK" } }
]
}
}
“Texas producers who are FHA- or VA-heavy, and not at a bank.” The tree is ANDed with flatFilters.
Your CRM as a filter
Scope any search to your own workspace:
"crmList": { "mode": "notIn", "lists": "any" }hides everyone already on one of your lists. Prospecting without re-finding people you have."crmList": { "mode": "in", "lists": ["list_…"] }runs a search over just a list, so you can re-rank or re-export it.- For agents,
"losOnMyTeam": { "relationship": "doesNotWorkWith" }finds agents your company’s loan officers haven’t financed a buyer for.
Questions you can now ask
Each of these is one request. Swap the values and they’re yours.
Loan officers who moved to a non-bank lender this year and still produce in Dallas
{
"flatFilters": { "msa": "19100", "timeAtCompanyMonths": { "lte": 9 }, "units": { "gte": 12 } },
"advancedFilters": { "type": "not", "child": { "type": "filter", "field": "companyCategory", "op": "eq", "value": "BANK" } },
"period": "last12Months",
"sort": [{ "field": "scopedVolume", "order": "desc" }]
}
Agents in 78704 whose buyers almost always finance, and who spread referrals around
{
"flatFilters": { "zip": "78704", "percentUnitsMortgaged": { "gte": 80 }, "totalOriginatorsWorkedWith": { "gte": 5 } },
"locationSource": "production",
"sideDominance": ["buyer"],
"period": "last12Months"
}
Homeowners whose newest mortgage is from one lender, recorded before rates rose
{
"flatFilters": {
"county": "48453",
"loanLender": "mortgage_rocket",
"loanRecordedDate": { "lte": "2021" },
"loanMatchMode": "most_recent",
"ownerOccupancy": "owner_occupied"
}
}
$1M or more of FHA inside Orlando, from anyone, excluding my existing lists
{
"footprint": { "city": "Orlando", "state": "FL", "product": { "mix": "loanType", "key": "fha", "volume": { "gte": 1000000 } } },
"crmList": { "mode": "notIn", "lists": "any" },
"period": "last12Months"
}
Multi-state producers with a big month recently
{
"flatFilters": { "stateCount": { "gte": 3 }, "peakMonthVolume": { "gte": 10000000 }, "lastTransactionDate": { "gte": "2026-07" } },
"period": "last12Months"
}
Save the ones you keep using
A filter you run more than once is worth a name. Saved filters store the exact body, validate it, and make it runnable from the app, the API, and an AI assistant.
Count first, then fetch
Every list endpoint has a sibling count endpoint that takes the identical body and returns only the total. It’s free, so size a query there, adjust, and only then fetch rows. The same body, unchanged, also works on the entity’s bulk-delivery endpoint when you want the whole list as a file.