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

# Authentication

> The bearer key, where it comes from, what it gets, and the one host it answers on.

Every request carries your key as a bearer token. A key starts with `zpka_`. It comes from the developer console
([Get an API key](/get-a-key)). It belongs to a plan ([Plans and limits](/guides/plans-and-limits)). It works on `/v1`
and on [the MCP endpoint](/mcp/overview) alike.

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

A missing, mistyped, deleted or expired key is `401 unauthorized`. A key whose plan subscription ended is
`403 subscription_required`. The Free plan is enough to bring it back. Keep the key out of code. Every snippet on this
site reads it from `GM_API_KEY`. On [Your keys](/keys) you roll the key to rotate it, or delete it if it ever leaks.

## What a key receives

Every endpoint answers on every key. The API does not serve the fields that identify a natural person on
`api.investorlift.com`. These fields are:

* the people behind an entity, their mailing addresses and skip-trace targets
* a parcel owner's identity
* listing agents' names, phones, emails and licence numbers
* the borrowers on a mortgage
* the party key and a person's or a trust's name on a lender's borrower rows
* the parties to an involuntary lien
* the agent named on a listing cycle

The API serves a company's name on a lender's borrower rows to every key. The fields above come back `null`, and the
record says so with `contact_redacted: true`. On the parcel routes (search, financing, history, listing history) the API
leaves these fields out of the object and carries no flag. The API does the same on the loan rows of a lender. The API
serves the rest of the row as normal. No endpoint refuses a request because it cannot serve these fields.

<Note>
  The API never serves contact fields on this host. The API names a registry investor by its registry name on every
  key, with `display_name` beside it to print. The registry name is the deed spelling, and it can be a person's when
  someone buys property in their own name. Member lists show companies and trusts only. A person, a trust or an
  owner-occupant that bought with no investor id comes back with a null name. The entities, the deals, the listings,
  the scores and the reasons are all there.
</Note>

## Where the API answers

| Host                           | What it is                                                                                                                  |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------- |
| `https://api.investorlift.com` | Production. Every example on this site runs against it, and the playground in the API reference calls it from your browser. |

Next: [the response envelope](/guides/concepts/envelope), [pagination](/guides/concepts/pagination) and
[rate limits](/guides/concepts/rate-limits).

## Partners and staff

Investorlift staff and contracted partners on the company network call the API on an internal host. They use a `gm_` key
(43 characters) that Investorlift Data Services issues. Those keys carry scopes. A scope gates **fields**, not endpoints:

| Scope         | What it adds                                                                                                                                                                                                                                                                                                                                                                                      |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `deals`       | Every endpoint. Deals, investors, properties, agents, Investorlift listings, short-term rentals, scores and reasons. What a `zpka_` key gets.                                                                                                                                                                                                                                                     |
| `contact`     | On `/v1`: the people behind an entity, their parsed names, mailing addresses and skip-trace targets. Also parcel owner identity, and listing agents' names, phones, emails and licence numbers. Also the borrowers on a mortgage, and the party key and a person's or a trust's name on a lender's borrower rows. Also the parties to an involuntary lien and the agent named on a listing cycle. |
| `mcp_contact` | The same fields over MCP, and only on single-record results. See [Keys and headers](/mcp/keys).                                                                                                                                                                                                                                                                                                   |

The `403 scope_required` code is reserved for a representation that is nothing but contact data. No route serves one
today.

A key that carries either contact scope must name **who asks** on every request. It does so with an `X-On-Behalf-Of`
header. The value is an opaque id of the person or org in the partner's own system, for example `user:12345`. The MCP
endpoint wants one of the prefixes `user:`, `key:`, `svc:` or `org:`, so a value that carries one works everywhere.

The API attributes the request to that user and meters it under a second rate-limit bucket. The API writes it into the
audit record for every response that carried contact data. If you omit the header on a contact-scope key, the API
answers `400 on_behalf_of_required`.

On `api.investorlift.com` you send none of this. The gateway sets `X-On-Behalf-Of` from your Investorlift account and
drops any value a caller sends.


## Related topics

- [API reference](/api-reference/introduction.md)
- [Introduction](/index.md)
- [The Investor object](/api-reference/objects/investor.md)
- [Your keys](/keys.md)
- [Who owns this house?](/guides/walkthroughs/who-owns-this-house.md)
