> ## 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.

# Quickstart

> Get a key, make one call and read the answer in about five minutes.

On this page you ask the API what investors did around one house in Scottsdale. Then you read the answer.

<Steps>
  <Step title="Get a key">
    Open [Get an API key](/get-a-key). Sign in with your Investorlift account, the account you use on the marketplace. If
    you have none, create one there. Accept the developer agreement once.

    Subscribe to the Free plan. The console asks for a card and keeps it on file. The Free plan charges nothing. Copy the
    key. It starts with `zpka_`.

    You can copy it again from the console's Keys and usage page each time you need it. [Your keys](/keys) says how to
    roll it and what to do if it leaks.

    Everything on this page works on the Free plan. [Plans and limits](/guides/plans-and-limits) says what a key can do
    each minute and each month.
  </Step>

  <Step title="Put the key in your shell">
    ```bash theme={null}
    export GM_API_KEY="zpka_..."
    ```

    Every snippet on this site reads the key from `GM_API_KEY`, so nothing you copy has a key in it. The Python snippets
    use `requests` (`pip install requests`). The Node ones need nothing but Node 18 or later.
  </Step>

  <Step title="Make the call">
    This request asks what investors did within two miles of 7522 E Cholla St, Scottsdale. It covers the whole history
    the data holds. It costs no credits and returns one row of totals, not a page of deals.

    <CodeGroup>
      ```bash curl theme={null}
      curl "https://api.investorlift.com/v1/deals/summary?lat=33.476917&lng=-111.920385&radius_miles=2" \
        -H "Authorization: Bearer $GM_API_KEY"
      ```

      ```javascript Node.js theme={null}
      const params = new URLSearchParams({ lat: "33.476917", lng: "-111.920385", radius_miles: "2" });
      const res = await fetch(`https://api.investorlift.com/v1/deals/summary?${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/deals/summary",
          params={"lat": 33.476917, "lng": -111.920385, "radius_miles": 2},
          headers={"Authorization": f"Bearer {os.environ['GM_API_KEY']}"},
          timeout=30,
      )
      r.raise_for_status()
      body = r.json()
      ```
    </CodeGroup>
  </Step>

  <Step title="Read the answer">
    ```json theme={null}
    {
      "data": {
        "n_deals": 10980,
        "n_investors": 5833,
        "n_parcels": 8596,
        "by_kind": { "flip": 1582, "wholesale": 570, "hold": 6321, "long_hold": 1717, "other": 657, "build": 133 },
        "median_bought_price": 295000,
        "median_sold_price": 405000,
        "median_gross_profit": 108000,
        "median_hold_days": 353
      },
      "meta": {
        "coverage": [{ "market": "phx", "data_end": "2026-08-27", "dataset_version": 1789636470 }],
        "terms": "Data: Investorlift Data Services. Public-record and MLS listing data licensed through BatchData; ..."
      }
    }
    ```

    Three things to know about it, and they hold for every other endpoint:

    <ResponseField name="data" type="object">
      The answer. Here it is one row of totals: 10,980 investor deals by 5,833 investors on 8,596 parcels inside the
      radius. The row also splits them by [deal kind](/guides/ideas). A list endpoint puts its rows here instead.
    </ResponseField>

    <ResponseField name="meta.coverage[]" type="array">
      Which markets answered and how fresh they are. `data_end` is the last deed in the data. The API measures **every**
      "days since" number from it, not from today. See [Coverage and freshness](/guides/concepts/coverage).
    </ResponseField>

    <ResponseField name="meta.coverage[].dataset_version" type="integer">
      Changes only at a rebuild of the tables. Put it in your cache key, and the cache invalidates itself at the next
      refresh. Keep a cached answer for at most 30 days. Drop it within a business day of a version change. Check the
      current version daily with `GET /v1/dataset`. The [cache window](/guides/terms) is the rule.
    </ResponseField>

    A list endpoint adds `page`. Follow `page.next_cursor` until it is null. Some list endpoints also add `summary`:
    totals over the whole filtered set, not this page. [The response envelope](/guides/concepts/envelope) has the rest.
  </Step>

  <Step title="Ask the real question">
    This is the call the API exists for. It asks which nearby investors are the best fit for a house you have under
    contract, and why.

    <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>

    Each row carries the investor, what they did inside the radius, and a score from 0 to 1. It also carries the
    **reasons** behind that score, in words you can show a user. The reasons say how close they buy, how recently, and if
    your price fits their band. They also say if the investor is a flipper and if they bought from a wholesaler before.
    [Buyers for a house under contract](/guides/walkthroughs/find-buyers) explains the response field by field.
  </Step>
</Steps>

## Where to go next

<CardGroup cols={3}>
  <Card title="The ideas you need" icon="lightbulb" href="/guides/ideas">
    Deal kinds, investor ids, scale, the contact block. Twenty minutes that make every response readable.
  </Card>

  <Card title="Walkthroughs" icon="map" href="/guides/walkthroughs/map">
    Nine common questions answered end to end, with real responses.
  </Card>

  <Card title="API reference" icon="code" href="/api-reference/introduction">
    One page per endpoint, with its parameters and fields generated from the code.
  </Card>
</CardGroup>

If the API answers with an error, the body is RFC 9457 with a `code` you can switch on. Every code has its own
section on the [Errors](/guides/concepts/errors) page.

<Note>
  No official SDK exists yet. Every guide shows the request in curl, Node.js and Python, and the reference playground
  generates more. The OpenAPI document at `https://api.investorlift.com/openapi.json` generates a typed client with
  openapi-typescript or openapi-python-client. Official packages will follow.
</Note>


## Related topics

- [Get an API key](/get-a-key.md)
- [Introduction](/index.md)
