Skip to main content
One call to GET /v1/investors answers the question “who buys in this ZIP now”. Give the ZIP as the location. A ZIP or a postal city is a location like a point or a viewport. Set bought_after to the market’s data end minus 90 days. Set sort=events_desc, the default order. It ranks by distinct purchase days inside the place. Each row carries that trailing count beside the investor’s market-wide facts. The same row says if a skip trace has anyone to look for.

1. The call

Scottsdale’s 85257, the purchases of the last 90 days of data, most purchase days first:
bought_after is an absolute date. Nothing bounds the purchases counted inside the place relative to today or to data_end. active_within_months keeps investors by their last purchase anywhere in the market, in months before data_end. It moves no count. The anchor is the market’s own clock, meta.coverage[].data_end (Coverage and freshness), not today. The data end runs weeks behind the day you ask. On the day of writing, the lag was between about three and five weeks across the loaded markets. So today minus 90 days shortens the window by that lag with no warning, and counts days the data does not hold yet. Read data_end first, from GET /v1/dataset (not metered) or from the meta.coverage[] of any earlier response. Subtract 90 days, and write the date. A market whose data_end is the last day of August opens its window at the start of June. Recompute it after every refresh. data_end moves, so a bought_after that you wrote once covers a longer window after each refresh. Rows with no purchase date leave the count once you set bought_after, and include_undated=true keeps them.

2. Or around a point

The place form measures no distance. When the question is “within a mile of this house”, not “in this ZIP”, give a point and a radius instead. Use the same filter and the same sort:
Each row then carries in_radius.nearest_distance_miles from the point. With a bare ZIP it is null. lat and lng beside zip are allowed. They are the reference point for that distance alone, and the ZIP stays the geometry. radius_miles beside zip is 400 geometry_conflict: one location per request. Over MCP the same question is godmode_investors_nearby with the same inputs: zip: ["85257"], bought_after: "2026-05-29" and sort: "events_desc", or latitude, longitude and radius_miles for the point form. Its concise format, the default, keeps the identity, operator_id, the contact counts and the geometry’s n_events, n_parcels, volume and last_bought_on. It leaves out in_radius.n_purchase_events, investor.n_deals, investor.n_purchase_events_12m, investor.days_since_last_purchase and investor.n_operator_members. Ask for response_format: "detailed" to read those.

3. Read the row

Each row is an investor list row: investor, in_radius, contact and the per-market blocks. The fields this ranking is about:
integer
Distinct purchase days inside the ZIP on or after bought_after: the trailing count, and what sort=events_desc ranks by. A bulk buy of four parcels on one day is one event. in_radius.n_parcels counts the parcels. in_radius.volume sums the prices the deeds state, or is null when no deed here carries a price. in_radius.last_bought_on is the latest of those days. The count is purchases alone: in_radius.last_deal_on also moves on a sale or a transfer inside the ZIP, and is for display.
mixed
The same investor across the whole market, untouched by the ZIP and the window. The first is every investment deal as buyer inside the area loaded for the market, all kinds and years. The second is the distinct purchase days in the 12 months before data_end. The third is the days from their last purchase anywhere to data_end, or null when they never bought.Read the pair together. Six purchase days here beside an n_deals in the hundreds is a large operator that works this neighbourhood among others. The same six beside n_deals: 6 is a buyer who works only here. The API counts every “days since” to data_end, never to today.
mixed
Rows that share an operator_id are one buying operation, and a fresh LLC per deal is common. Collapse them and contact them once. The API ranks and pages each id on its own. So an operator with three ids can take three places in this ranking and fall across two pages. Keep the row whose id equals operator_id as the visible one, and never sum the counts across the members.Group by it within one response. Store the investor ids, not the operator id, which can move to another member after a refresh. Same buyer, cash right now has the whole rule.
mixed
The contact facts every key sees. The first is how many person-and-address pairings a skip trace can start from. The second says if a natural person appears among the deed names. The third says if one of them has a non-generic house address on a deed. The two flags also appear on investor.The API does not serve the identifying fields of the block (primary_address, mailing_addresses, person_members, skip_trace_targets) on this host. They are null with contact_redacted: true while the counts stand, so the block itself is never null. A row with has_person_member: false and n_skip_trace_targets: 0 is an entity with no person on any deed. The next step is the corporate registry, not a skip trace.
integer
The whole ZIP after the filters, not the page: the total the pages walk. summary.by_buyer_status counts the deal rows behind it by buyer status. The unclassified, excluded and unknown buyers have no investor id and never appear as rows here.

Narrow it

  • investor_deals_min=2 keeps the repeat buyers: at least two purchase days inside the ZIP in the window. The API applies it after the other filters.
  • kind=flip,wholesale counts only the purchases that ended in a flip or a double close. So the ranking becomes the flippers and the wholesalers of the ZIP. investor_kind=FLIPPER keeps the investors the registry classes as flippers, whatever they bought here. Filters in plain words lists the rest.
  • By default the list hides institutional investors (iBuyers, production builders, bulk landlords). They are often a ZIP’s largest buyers by volume. scale=individual,small,mid,large,institutional puts them in the ranking. scale=institutional shows them alone.

What this list is not

  • A relative window on the count. bought_after is a date you compute from data_end, because the API does not know today. The one relative window you set, active_within_months, keeps or drops whole investors by their market-wide recency. The flag filters (buys_wholesale, buys_at_auction, buys_reo, uses_private_lender) count back from data_end the same way. None of them touches in_radius.n_purchase_events. A window computed from today is shorter than it looks by the data end’s lag.
  • A ring count. The counts are for the one geometry you asked for, and the API computes no concentric rings. To count an investor’s purchases within a quarter mile and within a mile, send two requests with two radii. No field on a row says how the ZIP’s count divides by distance.
  • Market-wide beside in-place. investor.n_deals, investor.n_purchase_events_12m and investor.days_since_last_purchase ignore the ZIP and the window. The trailing count for this place is in_radius.n_purchase_events and nothing else on the row.
  • One ZIP on Free and Starter. On those plans a ZIP list or a city is 403 plan_limit, which names the limit (Plans and limits). From Growth a request takes up to 50 ZIPs or a city. A request with more than six ZIPs or a city waits behind other large queries. A ZIP no loaded market carries is 422 outside_coverage, which names it. The API refuses the whole list when one ZIP is unknown.
  • Per id, not per operator. The counts are the id’s. An operation spread over several LLCs appears once per id, and you fold it with operator_id.
  • Registered investors only. A household, a custodian trust or an unnamed buyer never appears as a row. summary.by_buyer_status counts them, and GET /v1/deals?zip=85257&buyer_status=unclassified,excluded,unknown lists the deals behind them (buyer_status=unclassified alone is the households).
  • Charged per investor. On the public tier each investor new to your account is one credit. The same investor again is free while the plan has credit (Plans and limits).

Partners and staff

On the internal host a key with the contact scope gets the identifying fields the counts describe, on the same row. These are contact.skip_trace_targets[], contact.person_members[] and the mailing addresses. A skip-trace target is a person paired with an address, and the array lists the best first. So the ranking and the reach-out come from one call. Everything above this heading reads the same on both hosts.