> ## Documentation Index
> Fetch the complete documentation index at: https://developers.investorlift.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Who should I call?

> Rank the investors around a house you have under contract and read the reasons behind each score.

You have 7522 E Cholla St, Scottsdale under contract at \$410,000 and it needs a major rehab. Ask for ranked buyers
within two miles:

<CodeGroup>
  ```bash curl theme={null}
  curl "https://api.investorlift.com/v1/buyers/match?lat=33.476917&lng=-111.920385&radius_miles=2&subject_asking_price=410000&subject_condition=MAJOR_REHAB&subject_segment=SFR" \
    -H "Authorization: Bearer $GM_API_KEY"
  ```

  ```javascript Node.js theme={null}
  const params = new URLSearchParams({
    lat: "33.476917",
    lng: "-111.920385",
    radius_miles: "2",
    subject_asking_price: "410000",
    subject_condition: "MAJOR_REHAB",
    subject_segment: "SFR",
  });
  const res = await fetch(`https://api.investorlift.com/v1/buyers/match?${params}`, {
    headers: { Authorization: `Bearer ${process.env.GM_API_KEY}` },
  });
  if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
  const body = await res.json();
  ```

  ```python Python theme={null}
  import os

  import requests

  r = requests.get(
      "https://api.investorlift.com/v1/buyers/match",
      params={
          "lat": 33.476917,
          "lng": -111.920385,
          "radius_miles": 2,
          "subject_asking_price": 410000,
          "subject_condition": "MAJOR_REHAB",
          "subject_segment": "SFR",
      },
      headers={"Authorization": f"Bearer {os.environ['GM_API_KEY']}"},
      timeout=30,
  )
  r.raise_for_status()
  body = r.json()
  ```
</CodeGroup>

## The score and the reasons

The first thing to read on a row is why it scored what it did. Here is one, ranked 14th of the 5,813 investors
scored in this radius:

```json theme={null}
{
  "investor": { "id": "inv_0a20a550f33b", "name": "ZAK VENTURES LLC", "scale": "large", "n_deals": 775 },
  "score": 0.8291,
  "gate": 1,
  "reasons": [
    { "factor": "proximity",       "weight": 0.3,  "value": 0.8185, "detail": "12 purchases (12 parcels) within 2 mi, nearest 0.10 mi" },
    { "factor": "recency",         "weight": 0.25, "value": 0.9886, "detail": "last bought 7 days before the data's end date (2026-08-12); 81 purchase events in 24 months" },
    { "factor": "price_fit",       "weight": 0.2,  "value": 0.4586, "detail": "$410k is above their 5-year band $210k-$289k (238 priced purchases)" },
    { "factor": "strategy",        "weight": 0.1,  "value": 1,      "detail": "FLIPPER (STRONG); subject is MAJOR_REHAB" },
    { "factor": "segment",         "weight": 0.05, "value": 0.894,  "detail": "89% of their deals are SFR" },
    { "factor": "wholesale_buyer", "weight": 0.1,  "value": 1,      "detail": "bought 36 wholesale contracts since 2021, last 2026-07" }
  ]
}
```

<ResponseField name="score" type="number">
  0 to 1, best first. `gate` times the weighted sum of the reason values, rounded to four decimals. Compare scores
  only within one response.
</ResponseField>

<ResponseField name="reasons[].detail" type="string">
  The sentence to show a user. The API already writes it for a person: no ids, no internal names.
</ResponseField>

This buyer is very close, very active, a flipper and a documented wholesale buyer. But \$410k is above what they
usually pay, so `price_fit` is only 0.46. The
[endpoint page](/api-reference/endpoints/buyers-match) has every factor, and says how the API rescales the weights
when it cannot score one factor.

## The proof and the contact

```json theme={null}
{
  "in_radius": { "n_events": 12, "n_parcels": 12, "n_flips": 3, "volume": 3119500, "nearest_distance_miles": 0.1 },
  "sample_deals": [
    { "id": "deal_4fd125ba9e27079bcdbe2d4968e313d8", "kind": "flip", "address_short": "7412 E Cambridge Ave",
      "bought_on": "2017-05-16", "bought_price": 242500, "sold_on": "2017-07-13", "sold_price": 282500,
      "gross_profit": 40000, "distance_miles": 0.1 }
  ],
  "contact": {
    "primary_address": { "street": "7522 E SAGUARO LN", "city": "SCOTTSDALE", "state": "AZ", "zip": "85257", "kind": "HOUSE", "is_generic": false },
    "person_members": [{ "name": "RIVERA DANA", "name_order": "surname_first", "given": "DANA", "surname": "RIVERA" }],
    "skip_trace_targets": [{ "given": "DANA", "surname": "RIVERA", "address": { "street": "7522 E SAGUARO LN", "city": "SCOTTSDALE", "state": "AZ", "zip": "85257" }, "basis": "person_home" }]
  },
  "contact_redacted": false
}
```

<ResponseField name="in_radius" type="object">
  What they did **inside your radius**, after your filters. The `investor` block beside it is their whole-market
  profile, so it is normal when the two numbers differ.
</ResponseField>

<ResponseField name="sample_deals[]" type="array">
  Up to five of their nearest deals here. Proof to show the user.
</ResponseField>

<ResponseField name="contact.skip_trace_targets[]" type="array">
  A person paired with an address, best first: "send these to a skip-trace vendor in this order". This host does not
  serve it: the whole block is null and `contact_redacted` is `true`.
</ResponseField>

<ResponseField name="summary.n_investors_ranked" type="integer">
  5,813 here: the whole radius, not the page.
</ResponseField>

## Things you can change

* **Leave out the subject facts** and the ranking is proximity, recency and documented wholesale buying only.
* **Send `subject_arv=560000`** instead of the asking price, or with it. The API uses each flipper's own
  buy-to-resale ratio to convert an after-repair value into the price that flipper is likely to pay.
* **Tune the weights per request** with `w_price_fit=0.4`. The effective weights come back in `meta.weights`.
* **Narrow the field**: `active_within_months=12` drops anyone with no purchase in the last year.
  `buys_wholesale=true` keeps only investors with a documented purchase from a wholesaler.
  `investor_kind_exclude=WHOLESALER` removes the competition.

<CodeGroup>
  ```bash curl theme={null}
  curl "https://api.investorlift.com/v1/buyers/match?lat=33.476917&lng=-111.920385&radius_miles=2&subject_arv=560000&subject_condition=MAJOR_REHAB&w_price_fit=0.4&active_within_months=12&buys_wholesale=true&investor_kind_exclude=WHOLESALER" \
    -H "Authorization: Bearer $GM_API_KEY"
  ```

  ```javascript Node.js theme={null}
  const params = new URLSearchParams({
    lat: "33.476917",
    lng: "-111.920385",
    radius_miles: "2",
    subject_arv: "560000",
    subject_condition: "MAJOR_REHAB",
    w_price_fit: "0.4",
    active_within_months: "12",
    buys_wholesale: "true",
    investor_kind_exclude: "WHOLESALER",
  });
  const res = await fetch(`https://api.investorlift.com/v1/buyers/match?${params}`, {
    headers: { Authorization: `Bearer ${process.env.GM_API_KEY}` },
  });
  if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
  const body = await res.json();
  ```

  ```python Python theme={null}
  import os

  import requests

  r = requests.get(
      "https://api.investorlift.com/v1/buyers/match",
      params={
          "lat": 33.476917,
          "lng": -111.920385,
          "radius_miles": 2,
          "subject_arv": 560000,
          "subject_condition": "MAJOR_REHAB",
          "w_price_fit": 0.4,
          "active_within_months": 12,
          "buys_wholesale": "true",
          "investor_kind_exclude": "WHOLESALER",
      },
      headers={"Authorization": f"Bearer {os.environ['GM_API_KEY']}"},
      timeout=30,
  )
  r.raise_for_status()
  body = r.json()
  ```
</CodeGroup>

`w_activity=1` multiplies every score by the probability that the buyer buys again soon. It is off by default. See
[Same buyer, cash right now](/guides/walkthroughs/same-buyer).


## Related topics

- [Introduction](/index.md)
- [Who is this lender?](/guides/walkthroughs/profile-a-lender.md)
- [Top buyers in a place](/guides/walkthroughs/top-buyers.md)
- [Errors](/guides/concepts/errors.md)
- [Connecting a client](/mcp/connect.md)
