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

# List every loan of one lender

> Every loan of one lender, newest first: the parcel, the source table, the lender as recorded, the amount and terms as filed. Also the deal it financed and its outcome, one row per instrument (`source` picks one table).

A geometry resolves to the H3 res-8 cells whose centre is inside it: a hex edge, not the circle. This host does not serve the borrowers of a recorded row: the rows omit them. With Accept: text/csv the whole filtered set as a CSV file.

[Filters, sorts and the one-row-per-instrument rule](https://developers.investorlift.com/api-reference/endpoints/lenders-loans).



## OpenAPI

````yaml /openapi.json get /v1/lenders/{id}/loans
openapi: 3.1.0
info:
  title: God Mode API
  version: 0.33.1
  description: >-
    You have a house to sell, usually a wholesale contract. You want to know
    **who nearby buys houses like this one and how to reach them**. County deed
    records already hold the answer. This API reads them for each loaded market
    and serves three things: deals, investors and a ranking. On every response,
    `meta.coverage[]` lists the markets and the area each covers.


    **Deals** are every investment purchase, flip, wholesale and current
    investor holding. **Investors** are the buyers behind them, grouped so that
    the LLCs of an operator and the person behind them count as one. **A
    ranking** says, for a given house, which investors are the best fit and why.


    The documentation site at https://developers.investorlift.com carries the
    guides, the walkthroughs, the error catalogue and the connection steps for
    MCP clients. https://developers.investorlift.com/llms.txt indexes the site
    for a model. This document is the machine-readable reference behind the API
    tab of the site.


    **Start here.** Ranked buyers for a house at 7522 E Cholla St, Scottsdale,
    under contract at $410,000 and in need of a major rehab:


    ```

    GET
    https://api.investorlift.com/v1/buyers/match?lat=33.476917&lng=-111.920385&radius_miles=2&subject_asking_price=410000&subject_condition=MAJOR_REHAB

    Authorization: Bearer zpka_...

    ```


    **Conventions.** Responses are `{ data, meta }`. Lists add `page` (an opaque
    cursor) and sometimes `summary`. A list parameter takes commas or repeated
    keys. Dates are YYYY-MM-DD. Ids carry a prefix: `deal_`, `prop_`, `inv_`,
    `agt_`, `wl_`, `wsr_`.


    Money is whole dollars. It is null, never 0, when the deed carries no price.
    Coordinates are WGS84. A location is a point and radius (`lat`, `lng`,
    `radius_miles`), a viewport (`bbox=west,south,east,north`) or a parcel
    (`property_id`).


    This host does not serve the people behind an entity, mailing addresses,
    owner identity, mortgage borrowers or lien parties. It does not serve the
    names, phones, emails and licence numbers of listing agents. It serves the
    entities, the deals, the listings and the ranking.


    Errors are RFC 9457 problem+json with a `code` to switch on. The catalogue
    is https://developers.investorlift.com/problems.json and the Errors page of
    the site. The field `meta.coverage[].dataset_version` changes only when a
    refresh rebuilds the tables of a market. Use it in cache keys, or poll `GET
    /v1/dataset`.


    **MCP.** The API serves the same data to Model Context Protocol clients at
    `POST https://api.investorlift.com/mcp` with the same key: twenty-six
    read-only tools, four resources, seven prompts. The MCP tab of the
    documentation site has the client setup. The file `mcp-manifest.json` beside
    this document lists the tools with their input schemas.


    Problem codes: 400 validation_error, 400 unknown_parameter, 400
    invalid_cursor, 400 geometry_required, 400 geometry_conflict, 400
    sort_requires_point, 400 invalid_id, 400 market_required, 401 unauthorized,
    403 quota_exceeded, 403 subscription_required, 403 payment_overdue, 403
    plan_limit, 404 not_found, 406 not_acceptable, 410 gone, 422
    outside_coverage, 422 ambiguous_apn, 422 ambiguous_address, 422
    csv_cap_exceeded, 422 listings_unavailable, 422 agents_unavailable, 422
    lenders_unavailable, 422 wholesale_unavailable, 422 str_unavailable, 422
    cash_sale_unavailable, 422 auction_unavailable, 422 parcels_unavailable, 422
    addresses_unavailable, 422 dated_refused, 422 history_unavailable, 400
    quicklist_unavailable, 400 dataset_unavailable, 429 rate_limited, 500
    internal_error, 503 database_unavailable, 503 pool_saturated, 503
    ledger_unavailable, 504 statement_timeout.
servers:
  - url: https://api.investorlift.com
security:
  - bearerAuth: []
tags:
  - name: buyers
    x-group: Buyers
    description: >-
      Which investors are the best fit for this house: the API ranks nearby
      investors against a subject property and explains each score.
  - name: deals
    x-group: Deals
    description: >-
      What occurred around a location: deals for a table, cells for a map,
      summary stats, and one deal by id.
  - name: investors
    x-group: Investors
    description: >-
      Who the buyers are: investors active in an area, a full profile, and their
      metro-wide history. A search finds an investor by any name they buy under.
  - name: properties
    x-group: Properties
    description: >-
      One parcel: find it from a point or an APN, then read its facts, owner
      information, short-term rental licence and every deal on it. The owner
      information covers investor holdings and business-use short-term rentals.
  - name: agents
    x-group: Listing agents
    description: >-
      Who the listing agents are: find one by name or licence number, then read
      the profile and every listing of theirs. The profile holds the licence,
      the brokerages, the listing counts and the investors they belong to.
  - name: wholesale
    x-group: Investorlift listings
    description: >-
      Investorlift listings as wholesale transactions: the houses listed, and
      what the county deeds show for each (closed, to whom, which deed). Also
      the listing companies, and what each investor bought off Investorlift.
  - name: lenders
    x-group: Lenders
    description: >-
      Who lends on houses in a market: find a lender by any spelling of its
      name. Rank the lenders of a market, or of one ZIP, city or county. Read a
      profile: loans counted once across the open-lien and recorded-history
      tables, the open book, terms, geography and rankings. List every loan of
      one lender.
  - name: dataset
    x-group: Dataset and coverage
    description: >-
      What the API serves, how fresh it is and which data is available where.
      The dataset version and the last deed date of every market, for cache keys
      and freshness checks. The coverage matrix, with a place lookup.
  - name: contract
    x-group: By contract
    description: >-
      Routes sold per jurisdiction under an order form and not reachable on a
      self-serve key. Ask through the console.
externalDocs:
  description: >-
    The documentation site: the guides, the walkthroughs, the error catalogue
    and the MCP connection steps.
  url: https://developers.investorlift.com
paths:
  /v1/lenders/{id}/loans:
    get:
      tags:
        - lenders
      summary: List every loan of one lender
      description: >-
        Every loan of one lender, newest first: the parcel, the source table,
        the lender as recorded, the amount and terms as filed. Also the deal it
        financed and its outcome, one row per instrument (`source` picks one
        table).


        A geometry resolves to the H3 res-8 cells whose centre is inside it: a
        hex edge, not the circle. This host does not serve the borrowers of a
        recorded row: the rows omit them. With Accept: text/csv the whole
        filtered set as a CSV file.


        [Filters, sorts and the one-row-per-instrument
        rule](https://developers.investorlift.com/api-reference/endpoints/lenders-loans).
      operationId: listLenderLoans
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 16
          in: query
          name: market
          required: false
          description: >-
            Market code, for example phx. The loaded markets are in
            meta.coverage[]. Send it only when the id exists in more than one
            loaded market. 400 market_required says so, and a lender has the
            same id in every market it lent in. Otherwise the API uses the id's
            own market.
        - schema:
            default: both
            type: string
            enum:
              - open
              - recorded
              - both
          in: query
          name: source
          required: false
          description: >-
            Which rows to list. With open, the API lists open lien positions
            only. With recorded, it lists recorded history slots only, with
            duplicates as the history holds them. With both, the default, it
            lists one row per instrument: the open row where the instrument has
            one, else its recorded row.
        - schema:
            type: string
          in: query
          name: recorded_from
          required: false
          description: >-
            Keep loans recorded on or after this date, YYYY-MM-DD. With Accept:
            text/csv on api.investorlift.com you must send it (400 without it).
            So an export is a window of the book, never the whole of it.
        - schema:
            type: string
          in: query
          name: recorded_to
          required: false
          description: >-
            Keep loans recorded on or before this date, YYYY-MM-DD. With
            recorded_from, one year is
            recorded_from=2025-01-01&recorded_to=2025-12-31.
        - schema:
            minItems: 1
            type: array
            items:
              type: string
              enum:
                - CONSTRUCTION
                - HELOC
                - OTHER
              description: >-
                What the file says the loan is, read from its flags and loan
                type and never from the label. CONSTRUCTION: the construction
                flag or a "Building or Construction Loan" type. HELOC: the
                credit-line flag or a "Credit Line (Revolving)" type. OTHER:
                everything else, that is a purchase-money or refinance mortgage
                of any kind.
          in: query
          name: product
          required: false
          description: >-
            Keep only loans of these products (comma list or repeated key):
            CONSTRUCTION, HELOC, OTHER.
        - schema:
            minItems: 1
            type: array
            items:
              type: string
              enum:
                - LE_24M
                - 25_TO_120M
                - 121_TO_359M
                - GE_360M
                - UNKNOWN
              description: >-
                The loan term in months, from the file's term where it carries
                one, else from the maturity date less the recording date.
                LE_24M: up to 24 months, the bridge and fix-and-flip range.
                25_TO_120M: 25 to 120 months. 121_TO_359M: 121 to 359 months.
                GE_360M: 30 years and longer. UNKNOWN: neither a term nor a
                maturity on file, which is most hard-money rows.
          in: query
          name: term_band
          required: false
          description: >-
            Keep only loans in these term bands (comma list or repeated key):
            LE_24M, 25_TO_120M, 121_TO_359M, GE_360M, UNKNOWN.
        - schema:
            minItems: 1
            type: array
            items:
              type: string
              minLength: 1
              maxLength: 80
          in: query
          name: loan_type
          required: false
          description: >-
            Keep only loans whose loan_type is one of these, as the file writes
            it (comma list or repeated key), for example "New Conventional" or
            "FHA".
        - schema:
            minItems: 1
            type: array
            items:
              type: string
              minLength: 1
              maxLength: 80
          in: query
          name: property_type
          required: false
          description: >-
            Keep only loans on parcels whose property_type_category is one of
            these, as the assessor feed writes it (comma list or repeated key),
            for example "Residential".
        - schema:
            type: integer
            minimum: 0
            maximum: 9007199254740991
          in: query
          name: amount_min
          required: false
          description: >-
            Keep only loans with loan_amount at or above this, in whole dollars.
            The filter drops unpriced loans.
        - schema:
            type: integer
            minimum: 0
            maximum: 9007199254740991
          in: query
          name: amount_max
          required: false
          description: >-
            Keep only loans with loan_amount at or below this, in whole dollars.
            The filter drops unpriced loans.
        - schema:
            type: string
            pattern: ^\d{5}$
          in: query
          name: zip
          required: false
          description: Keep only loans on parcels in this 5-digit ZIP.
        - schema:
            type: string
            minLength: 1
            maxLength: 100
          in: query
          name: city
          required: false
          description: >-
            Keep only loans on parcels in this city, as the parcel table writes
            it (case does not matter).
        - schema:
            minItems: 1
            type: array
            items:
              type: string
              enum:
                - PURCHASE
                - NOT_PURCHASE
                - UNKNOWN
              description: >-
                The loan's purpose, that is if it financed a purchase, read from
                the recorded deeds and never from the file's label. PURCHASE: a
                priced deed on the parcel, $10,000 or more, is dated in the 45
                days up to and including the recording date. A deed after the
                loan is a later sale, never this loan's purchase. NOT_PURCHASE:
                the deed registry covers those 45 days, the parcel has priced
                deeds, and none falls in them. Such a loan is a refinance, a
                second, a HELOC or a construction draw. UNKNOWN: the deed
                registry does not cover the window: its deeds or the parcel's
                deeds start after the loan, or the market has none.
          in: query
          name: purpose
          required: false
          description: >-
            Keep only loans of these purposes by the deed link (comma list or
            repeated key): PURCHASE, NOT_PURCHASE, UNKNOWN. While the market's
            registry predates the deed link, the API answers 422
            lenders_unavailable.
        - schema:
            minItems: 1
            type: array
            items:
              type: string
              enum:
                - RESOLVED_BY_RESALE
                - REFINANCED
                - OPEN
                - FORECLOSED
                - UNKNOWN
              description: >-
                What became of a loan tied to a deal: a performance proxy read
                from the deed chain, never from a delinquency record or payment
                history. RESOLVED_BY_RESALE is a priced deed on the parcel after
                the loan, and REFINANCED is a later mortgage on it in either
                table before any resale. OPEN is an open lien position at the
                slice date and nothing later, and UNKNOWN is none of these
                because the chain runs out. FORECLOSED: a take-back deed on the
                parcel more than 90 days after the loan's recording, before any
                priced resale and any later mortgage. A take-back deed is a
                trustee's deed, a sheriff's deed or a deed in lieu, and the
                foreclosed block on the loan row carries it. A shorter gap is
                the auction buyer's own deed, not a foreclosure of this loan.
          in: query
          name: outcome
          required: false
          description: >-
            Keep only loans tied to a deal with these outcomes (comma list or
            repeated key): RESOLVED_BY_RESALE, REFINANCED, OPEN, FORECLOSED,
            UNKNOWN. A loan tied to no deal has no outcome, and the filter drops
            it. While the registry predates the deal link, the API answers 422
            lenders_unavailable.
        - schema:
            minItems: 1
            type: array
            items:
              type: string
              enum:
                - flip
                - wholesale
                - hold
                - long_hold
                - other
                - build
              description: >-
                What occurred on the deal. flip: bought, fixed and resold within
                about a year at a profit-shaped margin; wholesale: bought and
                resold in under 30 days, or a chain resale or round trip within
                90 (a double close); hold: bought and still owned at data_end, a
                confirmed holding or an un-resold purchase; long_hold: held over
                a year, then sold (a landlord exit); other: an investor resale
                that is not a clean flip. Reasons: a loss, a thin margin, a
                builder's new home resold, an iBuyer resale, or a chain resale
                of 3 to 12 months; build: a registered investor bought a lot or
                teardown, built a house on it during the hold, then sold. A
                builder's finished home bought and resold is other. On data
                built after 2026-09-17 the kind keeps only a single-family
                parcel held over 90 days, its house complete by the sale year. A
                market built on or before 2026-09-17 (meta.coverage[].loaded_at)
                counts every lot-to-build resale by a registered investor as a
                build until its next build.
          in: query
          name: deal_kind
          required: false
          description: >-
            Keep only loans tied to a deal of these kinds (comma list or
            repeated key): flip, wholesale, hold, long_hold, other, build. While
            the registry predates the deal link, the API answers 422
            lenders_unavailable.
        - schema:
            type: string
            pattern: ^inv_[0-9a-f]{12}$
          in: query
          name: investor_id
          required: false
          description: >-
            Keep only loans whose main borrower resolves to this registered
            investor: the investor's loans from this lender. The id is inv_
            followed by 12 hex characters, the loan row's investor_id. While the
            registry predates the borrower match, the API answers 422
            lenders_unavailable.
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
          in: query
          name: foreclosed
          required: false
          description: >-
            true keeps only loans followed by a take-back deed on the parcel
            (foreclosed set on the row). false keeps the rest. Default: every
            loan. A take-back deed is a trustee's deed, a sheriff's deed or a
            deed in lieu after the recording. While the registry predates the
            take-back join, the API answers 422 lenders_unavailable.
        - schema:
            type: string
            pattern: ^[0-9a-f]{15}$
          in: query
          name: cell
          required: false
          description: >-
            Keep only loans on parcels in this H3 cell. Send the index as a hex
            string at res 7 or 8, for example 8848eba59dfffff, as GET
            `/v1/lenders/{id}/cells` and `/v1/deals/cells` serve them. The API
            reads the resolution off the index (400 validation_error, code
            invalid_cell, otherwise). Do not send it with zip, city or a
            geometry (400 geography_conflict). While the registry predates the
            place rankings, the API answers 422 lenders_unavailable.
        - schema:
            type: number
            minimum: -90
            maximum: 90
          in: query
          name: lat
          required: false
          description: >-
            Point latitude (with lng). With radius_miles it is the geometry. The
            API resolves the circle to the H3 res-8 cells whose centre lies
            inside it, so its edge is a hex boundary. Do not send it with zip,
            city or county (400 geography_conflict). On a registry built before
            the place rankings, the API answers 422 lenders_unavailable.
        - schema:
            type: number
            minimum: -180
            maximum: 180
          in: query
          name: lng
          required: false
          description: Point longitude (with lat).
        - schema:
            type: number
            minimum: 0.25
            maximum: 20
          in: query
          name: radius_miles
          required: false
          description: >-
            Search radius in miles around the point or around the centre of the
            property_id parcel, 0.25 to 20 (default 2). Not allowed with bbox.
        - schema:
            type: string
          in: query
          name: bbox
          required: false
          description: >-
            Viewport as west,south,east,north (WGS84 degrees). West must be less
            than east, south less than north, and the diagonal at most 40 mi. It
            must intersect a loaded market's coverage bbox (422 outside_coverage
            otherwise). It can carry lat + lng (without radius_miles) as the
            reference point for distances and sort=distance.
        - schema:
            type: string
            pattern: ^prop_[0-9a-f]{32}$
          in: query
          name: property_id
          required: false
          description: >-
            Parcel geometry: search around the centre of that parcel, with
            radius_miles. Not allowed with lat, lng or bbox.
        - schema:
            default: recorded_desc
            type: string
            enum:
              - recorded_desc
              - recorded_asc
              - amount_desc
          in: query
          name: sort
          required: false
          description: >-
            Row order of a lender's loans: recorded_desc, the default, puts the
            newest recording first and undated rows last. With recorded_asc, the
            oldest recording comes first. With amount_desc, the largest loan
            amount comes first and unpriced rows last. This sort is slower on
            the largest lenders, which have no index in that order.
        - schema:
            default: 100
            type: integer
            minimum: 1
            maximum: 500
          in: query
          name: limit
          required: false
          description: Page size, 1-500 (default 100). Ignored by CSV.
        - schema:
            type: string
            minLength: 1
            maxLength: 4096
          in: query
          name: cursor
          required: false
          description: >-
            Opaque cursor from page.next_cursor of the previous page. A change
            of query, sort, weights or data version invalidates it (400
            invalid_cursor). Then restart from page 1.
        - schema:
            default: 'false'
            type: string
            enum:
              - 'true'
              - 'false'
          in: query
          name: require_current
          required: false
          description: >-
            true refuses the request with 422 dated_refused while the registry's
            source, the financing slice, is a dated snapshot. The default false
            serves it, and meta.dated[] carries the lenders and financing
            blocks.
        - schema:
            type: string
          in: path
          name: id
          required: true
          description: >-
            Lender id, len_ followed by 12 hex characters, for example
            len_d2028f0766fc. Take it from a search hit, a ranking row's
            lender.id or a parcel's financing block. The id is the same in every
            market and stable across data refreshes. The API follows an id from
            an earlier registry run to the current lender, and
            meta.resolved_from lists it. For a retired id with no successor, the
            API answers 410 gone.
      responses:
        '200':
          description: >-
            The lender's loans in one market, one page in the requested sort.
            With Accept: text/csv every filtered row as a CSV file. On
            api.investorlift.com the CSV needs a recorded_from window.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/LenderLoan'
                    description: The rows of this page.
                  page:
                    $ref: '#/components/schemas/Page'
                  meta:
                    $ref: '#/components/schemas/Meta'
                required:
                  - data
                  - page
                  - meta
                additionalProperties: false
                description: >-
                  The lender's loans in one market, one page in the requested
                  sort.
              example:
                data:
                  - market: phx
                    property_id: prop_cd126a2a572234fa8abfe853fc2ec706
                    address_short: 16647 W Saguaro Ln
                    city: SURPRISE
                    zip: '85388'
                    source: RECORDED
                    position: 2
                    loan_key: ad87846ae31cd527ab22a5669c9d78b8
                    in_both: false
                    lender_id: len_d2028f0766fc
                    lender_id_open: null
                    lender_disagrees: false
                    lender_name_as_recorded: KIAVI FUNDING INC
                    lender_class: NONBANK
                    identity_basis: NAME_FOLD
                    recording_date: '2026-06-10'
                    due_date: null
                    loan_amount: 374900
                    amount_outlier: false
                    current_balance: null
                    balance_outlier: null
                    on_resold_parcel: null
                    interest_rate: null
                    term_months: 360
                    term_band: GE_360M
                    loan_type: Building or Construction Loan
                    label: null
                    label_as_recorded: >-
                      Refi loans and 2nd trust deeds (purchase and non-purchase
                      money trust deeds)
                    product: CONSTRUCTION
                    product_proxy: RENTAL_TERM
                    product_basis: FILE
                    open_position: null
                    assigned_lender_name: null
                    blanket_group_id: null
                    blanket_n_parcels: null
                    county_fips: '04013'
                    property_type_category: Residential
                    purpose: PURCHASE
                    deed:
                      dt: '2026-05-05'
                      price: 280000
                      loan_to_price: 1.3389
                    deal: null
                    outcome: null
                    months_to_resolution: null
                    foreclosed: null
                    investor_id: inv_22038fe8a6b7
                    co_borrower_investor_ids: []
                    borrower_keys:
                      - e1a6d19e29f2
                    borrower_match: ENTITY_NAME
                    as_of: '2026-06-25'
                    dated: true
                  - market: phx
                    property_id: prop_260df84a75ada00ba055803eeed91550
                    address_short: 1812 E Sagebrush St
                    city: GILBERT
                    zip: '85296'
                    source: OPEN
                    position: 1
                    loan_key: 2e78bbc1a066fe4af8bb1a5b25d9e9dc
                    in_both: false
                    lender_id: len_d2028f0766fc
                    lender_id_open: len_d2028f0766fc
                    lender_disagrees: false
                    lender_name_as_recorded: KIAVI FUNDING INC
                    lender_class: NONBANK
                    identity_basis: NAME_FOLD
                    recording_date: '2026-06-09'
                    due_date: null
                    loan_amount: 446850
                    amount_outlier: false
                    current_balance: 446850
                    balance_outlier: false
                    on_resold_parcel: false
                    interest_rate: null
                    term_months: null
                    term_band: UNKNOWN
                    loan_type: Building or Construction Loan
                    label: null
                    label_as_recorded: null
                    product: CONSTRUCTION
                    product_proxy: null
                    product_basis: null
                    open_position: 1
                    assigned_lender_name: KIAVI FUNDING INC
                    blanket_group_id: null
                    blanket_n_parcels: null
                    county_fips: '04013'
                    property_type_category: Residential
                    purpose: PURCHASE
                    deed:
                      dt: '2026-06-09'
                      price: 475000
                      loan_to_price: 0.9407
                    deal: null
                    outcome: null
                    months_to_resolution: null
                    foreclosed: null
                    investor_id: inv_b077ac90fead
                    co_borrower_investor_ids: []
                    borrower_keys:
                      - 22d2dfb566a4
                    borrower_match: OWNER_OF_RECORD
                    as_of: '2026-06-25'
                    dated: true
                page:
                  next_cursor: >-
                    eyJ2IjoxLCJydW4iOiIxNzg5NTMzMTgwIiwicSI6ImFhNGMzOWI2OTMyYTU3NWFlYzRiMDExMjAyMGMxMWQ5MDc1MjcyNmUwNzk0YTNjNjUyZTFkODRiMjViMGRlZWEiLCJrIjpbIjIwMjYtMDYtMDkiLCIyNjBkZjg0YTc1YWRhMDBiYTA1NTgwM2VlZWQ5MTU1MCIsIk9QRU4iLDFdfQ
                  limit: 2
                  returned: 2
                meta:
                  generated_at: '2026-09-15T12:00:00.000Z'
                  coverage:
                    - market: phx
                      state: AZ
                      counties:
                        - fips: '04013'
                          name: Maricopa
                          data_end: '2026-08-12'
                        - fips: '04021'
                          name: Pinal
                          data_end: '2026-08-06'
                      bbox:
                        - -113.332773
                        - 32.46915
                        - -110.455491
                        - 33.999503
                      data_end: '2026-08-27'
                      build_run_id: 3
                      registry_run: 11
                      registry_version: v6-auction
                      dataset_version: 1789533180
                      loaded_at: '2026-09-16T04:32:59.760Z'
                      metro_buy_to_resale_ratio: 0.719
                      universe_kind: metro
                      universe_zips: null
                      point_tolerance_miles: 20
                      n_parcels: 1836311
                      listings_data_end: '2026-08-31'
                      agents_data_end: '2026-08-31'
                      wholesale_as_of: '2026-09-09'
                      str_as_of: '2026-09-10'
                      str:
                        jurisdictions:
                          - name: APACHE_JUNCTION
                            regime: NOT_REQUIRED
                            coverage_reason: NO_REQUIREMENT
                            served: false
                            snapshot_only: false
                            licence_start: null
                            snapshot_date: null
                            feed_stale: false
                            sources: []
                            n_licensed: 0
                            n_pending: 0
                            n_expired: 0
                            n_advertised: 0
                            share_unmatched: null
                            share_assumed: null
                          - name: AVONDALE
                            regime: REQUIRED
                            coverage_reason: REQUIRED_NOT_PUBLISHED
                            served: false
                            snapshot_only: false
                            licence_start: null
                            snapshot_date: null
                            feed_stale: false
                            sources: []
                            n_licensed: 0
                            n_pending: 0
                            n_expired: 0
                            n_advertised: 0
                            share_unmatched: null
                            share_assumed: null
                      auction_counted: true
                      parcel_as_of: '2026-08-27'
                      address_as_of: null
                      parcel:
                        parcel_as_of: '2026-08-27'
                        n_parcels: 1836311
                        sale_mortgage_measured: false
                        financing:
                          as_of: '2026-06-25'
                          dated: true
                          dated_reason: dataset not in current delivery
                          n_parcels: 1611957
                          n_with_open_lien: 1032808
                          n_free_and_clear: 579149
                          n_avm: 1528967
                          n_involuntary: 192400
                          n_lenders: 76212
                        permits:
                          as_of: '2026-09-01'
                          n_permits: 2377496
                          n_parcels: 663045
                          n_unmatched: 355
                          jurisdictions:
                            - jurisdiction: PHOENIX
                              n_permits: 795764
                              last_issue_date: '2026-05-11'
                              windows_measured: null
                            - jurisdiction: MESA
                              n_permits: 330809
                              last_issue_date: '2026-05-29'
                              windows_measured: null
                            - jurisdiction: MARICOPA COUNTY
                              n_permits: 217628
                              last_issue_date: '2027-10-17'
                              windows_measured: null
                            - jurisdiction: SCOTTSDALE
                              n_permits: 182189
                              last_issue_date: '2024-11-05'
                              windows_measured: null
                            - jurisdiction: GOODYEAR
                              n_permits: 173391
                              last_issue_date: '2025-04-02'
                              windows_measured: null
                            - jurisdiction: GILBERT
                              n_permits: 160199
                              last_issue_date: '2025-04-07'
                              windows_measured: null
                            - jurisdiction: TEMPE
                              n_permits: 102909
                              last_issue_date: '2025-12-29'
                              windows_measured: null
                            - jurisdiction: BUCKEYE
                              n_permits: 94951
                              last_issue_date: '2026-03-18'
                              windows_measured: null
                            - jurisdiction: CHANDLER
                              n_permits: 94942
                              last_issue_date: '2026-05-29'
                              windows_measured: null
                            - jurisdiction: PEORIA
                              n_permits: 75435
                              last_issue_date: '2026-05-07'
                              windows_measured: null
                            - jurisdiction: QUEEN CREEK
                              n_permits: 59103
                              last_issue_date: '2026-04-24'
                              windows_measured: null
                            - jurisdiction: null
                              n_permits: 43845
                              last_issue_date: '2026-06-05'
                              windows_measured: null
                            - jurisdiction: PARADISE VALLEY
                              n_permits: 23135
                              last_issue_date: '2026-04-24'
                              windows_measured: null
                            - jurisdiction: AVONDALE
                              n_permits: 7961
                              last_issue_date: '2026-04-24'
                              windows_measured: null
                            - jurisdiction: MARICOPA
                              n_permits: 5732
                              last_issue_date: '2026-12-12'
                              windows_measured: null
                            - jurisdiction: YOUNGTOWN
                              n_permits: 3979
                              last_issue_date: '2026-06-05'
                              windows_measured: null
                            - jurisdiction: EL MIRAGE
                              n_permits: 1971
                              last_issue_date: '2026-04-13'
                              windows_measured: null
                            - jurisdiction: YUMA
                              n_permits: 1909
                              last_issue_date: '2009-01-15'
                              windows_measured: null
                            - jurisdiction: FOUNTAIN HILLS
                              n_permits: 767
                              last_issue_date: '2026-05-21'
                              windows_measured: null
                            - jurisdiction: ELMIRAGE
                              n_permits: 521
                              last_issue_date: '2025-08-08'
                              windows_measured: null
                            - jurisdiction: SUN CITY
                              n_permits: 133
                              last_issue_date: null
                              windows_measured: null
                            - jurisdiction: COCONINO COUNTY
                              n_permits: 63
                              last_issue_date: '2024-02-16'
                              windows_measured: null
                            - jurisdiction: PINAL COUNTY
                              n_permits: 54
                              last_issue_date: '2022-07-21'
                              windows_measured: null
                            - jurisdiction: APACHE JUNCTION
                              n_permits: 47
                              last_issue_date: '2025-05-13'
                              windows_measured: null
                            - jurisdiction: PIMA COUNTY
                              n_permits: 21
                              last_issue_date: '2016-10-24'
                              windows_measured: null
                            - jurisdiction: WITTMANN
                              n_permits: 8
                              last_issue_date: '2026-02-03'
                              windows_measured: null
                            - jurisdiction: JACKSON COUNTY
                              n_permits: 7
                              last_issue_date: null
                              windows_measured: null
                            - jurisdiction: LEWISVILLE
                              n_permits: 5
                              last_issue_date: '2024-02-07'
                              windows_measured: null
                            - jurisdiction: MONTGOMERY
                              n_permits: 4
                              last_issue_date: '2023-06-05'
                              windows_measured: null
                            - jurisdiction: RIVERSIDE COUNTY
                              n_permits: 3
                              last_issue_date: '2026-06-20'
                              windows_measured: null
                            - jurisdiction: LITCHFIELD PARK
                              n_permits: 3
                              last_issue_date: null
                              windows_measured: null
                            - jurisdiction: APACHE JUNCTION - SEWER UTILITY
                              n_permits: 2
                              last_issue_date: '2026-05-07'
                              windows_measured: null
                            - jurisdiction: FORT WORTH
                              n_permits: 2
                              last_issue_date: null
                              windows_measured: null
                            - jurisdiction: YAVAPAI COUNTY
                              n_permits: 1
                              last_issue_date: null
                              windows_measured: null
                            - jurisdiction: LOCUST GROVE
                              n_permits: 1
                              last_issue_date: null
                              windows_measured: null
                            - jurisdiction: ORO VALLEY
                              n_permits: 1
                              last_issue_date: null
                              windows_measured: null
                            - jurisdiction: TANGIPAHOA
                              n_permits: 1
                              last_issue_date: '2019-05-28'
                              windows_measured: null
                        owner_profile:
                          as_of: '2026-09-09'
                          n_parcels: 1611077
                          n_multi: 646963
                          n_portfolio_5: 277841
                        history:
                          first_week: '2025-07-24'
                          last_week: '2026-09-09'
                          zips:
                            - '85251'
                          n_parcels: 18774
                          n_events: 236022
                          n_weeks: 62
                          domains:
                            tax:
                              first_week: '2025-07-24'
                              last_week: '2026-09-09'
                              n_events: 18597
                            deed:
                              first_week: '2025-07-24'
                              last_week: '2026-09-09'
                              n_events: 17615
                            sale:
                              first_week: '2025-07-24'
                              last_week: '2026-09-09'
                              n_events: 1700
                            listing:
                              first_week: '2025-07-24'
                              last_week: '2026-09-09'
                              n_events: 21122
                            mailing:
                              first_week: '2025-07-24'
                              last_week: '2026-09-09'
                              n_events: 2128
                            vacancy:
                              first_week: '2025-07-24'
                              last_week: '2026-09-09'
                              n_events: 2583
                            financing:
                              first_week: '2025-12-02'
                              last_week: '2026-06-25'
                              n_events: 6420
                            occupancy:
                              first_week: '2025-07-24'
                              last_week: '2026-09-09'
                              n_events: 1297
                            ownership:
                              first_week: '2025-07-24'
                              last_week: '2026-09-09'
                              n_events: 3238
                            structure:
                              first_week: '2025-07-24'
                              last_week: '2026-09-09'
                              n_events: 2548
                            valuation:
                              first_week: '2025-07-24'
                              last_week: '2026-06-25'
                              n_events: 83657
                            assessment:
                              first_week: '2025-07-24'
                              last_week: '2026-09-09'
                              n_events: 16450
                            owner_profile:
                              first_week: '2025-07-24'
                              last_week: '2026-09-09'
                              n_events: 58404
                            classification:
                              first_week: '2025-07-24'
                              last_week: '2026-09-09'
                              n_events: 263
                      lenders:
                        as_of: '2026-06-25'
                        recordings_through: '2026-06-11'
                        counties:
                          - '04013'
                        history_capture_share: 0.183706
                        n_lender_ids: 32046
                        purchase_measured: true
                        investor_lending_measured: true
                        flips_measured: true
                        borrowers_measured: true
                        takebacks_measured: true
                        counties_measured: false
                        dated: true
                        n_parcels_uncovered: 224192
                  dated:
                    - block: financing
                      as_of: '2026-06-25'
                      reason: dataset not in current delivery
                    - block: lenders
                      as_of: '2026-06-25'
                      reason: dataset not in current delivery
                  terms: >-
                    Data: Investorlift Data Services. Public-record and MLS
                    listing data licensed through BatchData; municipal
                    short-term rental registries; Investorlift marketplace
                    records. Attribution and data-use terms:
                    https://developers.investorlift.com/guides/terms
            text/csv:
              schema:
                type: string
                description: >-
                  CSV with a header row: Market, Property id, Address, City,
                  ZIP, Source, Position, Loan key, In both, Lender id, Lender id
                  (open), Lender disagrees, Lender as recorded, Lender class,
                  Identity basis, Recording date, Due date, Loan amount, Amount
                  outlier, Current balance, Balance outlier, On resold parcel,
                  Interest rate, Term months, Term band, Loan type, Label, Label
                  as recorded, Product, Product proxy, Product basis, Open
                  position, Assigned lender, Blanket group id, Blanket parcels,
                  County FIPS, Property type, Purpose, Deed date, Deed price,
                  Loan to price, Deal id, Deal kind, Purchase loan, Outcome,
                  Investor id, Borrower keys, Borrower match, Foreclosed on,
                  Foreclosed instrument, Foreclosed by lender, As of, Dated. The
                  columns carry the JSON row's values, one cell per field. The
                  file has every filtered row in the requested sort, and the API
                  ignores cursor and limit. The cap is 50,000 rows (422
                  csv_cap_exceeded above), and X-Row-Cap is on every answer. The
                  filename is `lender-<id>-loans.csv`.
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            X-Rows:
              $ref: '#/components/headers/X-Rows'
            X-Dataset-Version:
              $ref: '#/components/headers/X-Dataset-Version'
            X-Data-End:
              $ref: '#/components/headers/X-Data-End'
            X-Row-Cap:
              $ref: '#/components/headers/X-Row-Cap'
        '400':
          description: >-
            Bad request (dataset_unavailable, geometry_conflict,
            geometry_required, invalid_cursor, invalid_id, market_required,
            quicklist_unavailable, sort_requires_point, unknown_parameter,
            validation_error)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              examples:
                geometry_conflict:
                  summary: Geometry conflict
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#geometry_conflict
                    title: Geometry conflict
                    status: 400
                    code: geometry_conflict
                    detail: >-
                      You cannot combine radius_miles with bbox. Send one
                      geometry only.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                geometry_required:
                  summary: Geometry required
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#geometry_required
                    title: Geometry required
                    status: 400
                    code: geometry_required
                    detail: >-
                      The request needs one geometry: lat and lng with
                      radius_miles, bbox, property_id, zip (a list) or city.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                invalid_cursor:
                  summary: Invalid cursor
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#invalid_cursor
                    title: Invalid cursor
                    status: 400
                    code: invalid_cursor
                    detail: >-
                      The API issued the cursor for another query. Restart from
                      page 1.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                invalid_id:
                  summary: Invalid id
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#invalid_id
                    title: Invalid id
                    status: 400
                    code: invalid_id
                    detail: >-
                      An investor id is inv_ followed by 12 hex characters. The
                      prefix is part of the id.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                market_required:
                  summary: Market required
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#market_required
                    title: Market required
                    status: 400
                    code: market_required
                    detail: >-
                      inv_0a20a550f33b exists in 2 loaded markets. Pass market=.
                      The codes are in markets[].
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                    markets:
                      - phx
                      - hou
                    errors:
                      - param: market
                        message: one of phx, hou
                        code: market_required
                sort_requires_point:
                  summary: Sort requires a reference point
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#sort_requires_point
                    title: Sort requires a reference point
                    status: 400
                    code: sort_requires_point
                    detail: >-
                      sort=distance needs a reference point: add lat and lng, or
                      property_id.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                unknown_parameter:
                  summary: Unknown parameter
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#unknown_parameter
                    title: Unknown parameter
                    status: 400
                    code: unknown_parameter
                    detail: >-
                      The query carries a parameter this endpoint does not
                      define: kind[]. Write the list as kind=flip,hold or as
                      repeated keys.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                    errors:
                      - param: kind[]
                        message: unknown parameter
                        code: unknown_parameter
                validation_error:
                  summary: Validation error
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#validation_error
                    title: Validation error
                    status: 400
                    code: validation_error
                    detail: radius_miles must be 20 or less.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                    errors:
                      - param: radius_miles
                        message: must be 20 or less
                        code: too_big
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          description: Unauthorized (unauthorized)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              examples:
                unauthorized:
                  summary: Unauthorized
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#unauthorized
                    title: Unauthorized
                    status: 401
                    code: unauthorized
                    detail: 'Send Authorization: Bearer with a current key.'
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '403':
          description: >-
            Forbidden (payment_overdue, plan_limit, quota_exceeded,
            subscription_required)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              examples:
                plan_limit:
                  summary: Plan limit
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#plan_limit
                    title: Plan limit
                    status: 403
                    code: plan_limit
                    detail: >-
                      The free plan searches within 5 miles of a point, a
                      viewport up to 10 miles across, or one ZIP code. Your zip
                      parameter lists 2 ZIP codes. Upgrade in the developer
                      console for city-wide and multi-ZIP searches.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                    tier: free
                    limit: geometry
                    max_radius_miles: 5
                    max_bbox_diagonal_miles: 10
                    max_zips: 1
                quota_exceeded:
                  summary: Quota exceeded
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#quota_exceeded
                    title: Quota exceeded
                    status: 403
                    code: quota_exceeded
                    detail: >-
                      Your requests spent the plan's credits for this billing
                      period (5000 of 5000). Wait for the period to reset on the
                      subscription's billing date, or upgrade in the developer
                      console.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                    used: 5000
                    line: 5000
                subscription_required:
                  summary: Subscription required
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#subscription_required
                    title: Subscription required
                    status: 403
                    code: subscription_required
                    detail: >-
                      This key has no active plan subscription. Subscribe in the
                      developer console.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                payment_overdue:
                  summary: Payment overdue
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#payment_overdue
                    title: Payment overdue
                    status: 403
                    code: payment_overdue
                    detail: >-
                      The subscription's payment is overdue and the grace period
                      passed. Update the card under Manage Billing in the
                      developer console.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '404':
          description: Not found (not_found)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              examples:
                not_found:
                  summary: Not found
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#not_found
                    title: Not found
                    status: 404
                    code: not_found
                    detail: No such deal in any loaded market.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '406':
          description: Not acceptable (not_acceptable)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              examples:
                not_acceptable:
                  summary: Not acceptable
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#not_acceptable
                    title: Not acceptable
                    status: 406
                    code: not_acceptable
                    detail: >-
                      Accept text/html names no representation this endpoint
                      produces (application/json).
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '410':
          description: >-
            Gone: a retired investor, agent or lender id, with superseded_by
            (gone)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              examples:
                gone:
                  summary: Gone
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#gone
                    title: Gone
                    status: 410
                    code: gone
                    detail: >-
                      The registry retired investor inv_003c1db2782c in run 8
                      (RETIRED). No current investor holds its names. Use
                      /v1/investors/search instead.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                    superseded_by: null
                    reason: RETIRED
                    market: phx
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '422':
          description: >-
            Unprocessable (addresses_unavailable, agents_unavailable,
            ambiguous_address, ambiguous_apn, auction_unavailable,
            cash_sale_unavailable, csv_cap_exceeded, dated_refused,
            history_unavailable, lenders_unavailable, listings_unavailable,
            outside_coverage, parcels_unavailable, str_unavailable,
            wholesale_unavailable)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              examples:
                agents_unavailable:
                  summary: Agents unavailable
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#agents_unavailable
                    title: Agents unavailable
                    status: 422
                    code: agents_unavailable
                    detail: >-
                      This market has no published agent registry. See
                      meta.coverage[].agents_data_end.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                auction_unavailable:
                  summary: Auction counts unavailable
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#auction_unavailable
                    title: Auction counts unavailable
                    status: 422
                    code: auction_unavailable
                    detail: >-
                      This market has no published foreclosure-auction counts:
                      its registry predates them. So the API cannot answer
                      buys_at_auction, buys_reo and bought_auction_kind there,
                      and meta.coverage[].auction_counted is false for it. Drop
                      the parameter to list every row.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                csv_cap_exceeded:
                  summary: CSV cap exceeded
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#csv_cap_exceeded
                    title: CSV cap exceeded
                    status: 422
                    code: csv_cap_exceeded
                    detail: >-
                      The filtered set has more than 50,000 rows; narrow the
                      recorded_from and recorded_to window or the filters.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                    cap: 50000
                    n_rows_at_least: 50001
                lenders_unavailable:
                  summary: Lenders unavailable
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#lenders_unavailable
                    title: Lenders unavailable
                    status: 422
                    code: lenders_unavailable
                    detail: >-
                      Market hou has no published lender registry
                      (meta.coverage[].lenders is null there). The API still
                      serves the financing block on parcels where the slice is.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                    markets:
                      - hou
                listings_unavailable:
                  summary: Listings unavailable
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#listings_unavailable
                    title: Listings unavailable
                    status: 422
                    code: listings_unavailable
                    detail: >-
                      You gave listing_status for a market with no published
                      listing tables. See meta.coverage[].listings_data_end.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                outside_coverage:
                  summary: Outside coverage
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#outside_coverage
                    title: Outside coverage
                    status: 422
                    code: outside_coverage
                    detail: >-
                      The point 40.712776, -74.005974 is outside every loaded
                      market's point tolerance (loaded: phx, hou). See
                      meta.coverage[].bbox and point_tolerance_miles on any list
                      response.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                str_unavailable:
                  summary: Short-term rental data unavailable
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#str_unavailable
                    title: Short-term rental data unavailable
                    status: 422
                    code: str_unavailable
                    detail: >-
                      This market has no published short-term rental tables. See
                      meta.coverage[].str_as_of.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                wholesale_unavailable:
                  summary: Wholesale transactions unavailable
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#wholesale_unavailable
                    title: Wholesale transactions unavailable
                    status: 422
                    code: wholesale_unavailable
                    detail: >-
                      This market has no published Investorlift wholesale
                      tables. See meta.coverage[].wholesale_as_of.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            X-Row-Cap:
              $ref: '#/components/headers/X-Row-Cap'
        '429':
          description: Rate limited, with Retry-After (rate_limited)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              examples:
                rate_limited:
                  summary: Rate limited
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#rate_limited
                    title: Rate limited
                    status: 429
                    code: rate_limited
                    detail: >-
                      The request exceeded the per-key budget. Retry in 12
                      seconds.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                    retry_after: 12
                    bucket: key
          headers:
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '500':
          description: Internal error (internal_error)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              examples:
                internal_error:
                  summary: Internal error
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#internal_error
                    title: Internal error
                    status: 500
                    code: internal_error
                    detail: The request failed. Quote request_id when you report it.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '503':
          description: >-
            Unavailable, with Retry-After on pool_saturated and
            ledger_unavailable (database_unavailable, ledger_unavailable,
            pool_saturated)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              examples:
                database_unavailable:
                  summary: Database unavailable
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#database_unavailable
                    title: Database unavailable
                    status: 503
                    code: database_unavailable
                    detail: >-
                      The service failed to reach the database and did not run
                      the request.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                ledger_unavailable:
                  summary: Ledger unavailable
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#ledger_unavailable
                    title: Ledger unavailable
                    status: 503
                    code: ledger_unavailable
                    detail: >-
                      The credit ledger is unreachable. The API charged nothing.
                      Retry in 5 seconds.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
                    retry_after: 5
                pool_saturated:
                  summary: Pool saturated
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#pool_saturated
                    title: Pool saturated
                    status: 503
                    code: pool_saturated
                    detail: >-
                      No pooled connection was free. The service did not run the
                      request.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
          headers:
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '504':
          description: Statement timeout (statement_timeout)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              examples:
                statement_timeout:
                  summary: Statement timeout
                  value:
                    type: >-
                      https://developers.investorlift.com/guides/concepts/errors#statement_timeout
                    title: Statement timeout
                    status: 504
                    code: statement_timeout
                    detail: >-
                      The query exceeded the 10 second statement timeout. Narrow
                      the geometry or filters.
                    instance: /v1/lenders/{id}/loans
                    request_id: 6f1c2a8e-3b7d-4f21-9a0c-2e5b81d7a4f3
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
components:
  schemas:
    LenderLoan:
      type: object
      properties:
        market:
          type: string
          description: Market code, for example phx.
        property_id:
          type: string
          pattern: ^prop_[0-9a-f]{32}$
          description: >-
            The parcel: the key to GET `/v1/properties/{property_id}` and its
            financing block.
        address_short:
          description: >-
            Street address without city, for example "7522 E Cholla St". Null
            when the parcel is not in the parcel table.
          type:
            - string
            - 'null'
        city:
          description: City, upper case. Null when the parcel is not in the parcel table.
          type:
            - string
            - 'null'
        zip:
          description: 5-digit ZIP. Null when the parcel is not in the parcel table.
          type:
            - string
            - 'null'
        source:
          type: string
          enum:
            - OPEN
            - RECORDED
          description: >-
            Which table the row comes from. OPEN: an open lien position at the
            slice date, 1 to 4 per parcel, with the balance, rate, term and
            maturity the open-lien table carries. RECORDED: a slot of the
            recorded mortgage history, the 5 newest per parcel, with older ones
            lost. The same instrument is in both tables when the dates and
            amounts match, and in_both says so.
        position:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: >-
            The row's slot in its source table. For OPEN it is the lien position
            (1 is senior). For RECORDED it is the history slot: 1 is the oldest
            kept, the highest filled slot is the newest.
        loan_key:
          type: string
          description: >-
            The instrument's key, 32 hex characters, from the parcel, the
            recording date and the amount. It is the same on an open row and its
            recorded twin, so you can join rows across source. Not an id to
            store across refreshes.
        in_both:
          type: boolean
          description: >-
            True when the instrument is in both tables. That is an open row and
            a recorded slot on the same parcel with the same recording date and
            amount.
        lender_id:
          type: string
          pattern: ^len_[0-9a-f]{12}$
          description: >-
            The lender of record: the recorded history's lender on an instrument
            in both tables, the row's own otherwise. Equals the path id on this
            route.
        lender_id_open:
          anyOf:
            - type: string
              pattern: ^len_[0-9a-f]{12}$
              description: >-
                Lender id: len_ followed by 12 hex characters, for example
                len_3f9a1c27b4e0. The registry mints the id from the lender's
                folded name, so the same lender carries the same id in every
                market, stable across data refreshes. A hand-kept dictionary row
                can merge two spellings into one lender. The API then follows
                the old id from the earlier registry run to that lender and
                lists it in meta.resolved_from. A retired id with no successor
                answers 410 gone. Store the whole id, prefix included, as the
                identity.
            - type: 'null'
          description: >-
            The lender the open-lien table names for this instrument. It equals
            lender_id unless the two tables disagree (lender_disagrees). Null on
            a recorded row with no open twin, and when that lender is below the
            person gate.
        lender_disagrees:
          type: boolean
          description: >-
            True when the recorded history and the open table name different
            lenders for this instrument. That is the insurer (HUD, the VA)
            against the servicer, or a spelling the registry at as_of does not
            yet join. False when the instrument is in one table only.
        lender_name_as_recorded:
          description: >-
            The lender name on this row as the file writes it, for example
            LENDINGHOME FUNDING CORP under Kiavi's id. This is the spelling the
            parcel's financing block serves. Null when the file left it blank.
          type:
            - string
            - 'null'
        lender_class:
          anyOf:
            - type: string
              enum:
                - BANK
                - NONBANK
                - PRIVATE
                - INDIVIDUAL
                - GOVERNMENT
              description: >-
                How the lender name reads. BANK: a bank, credit union or thrift.
                NONBANK: a mortgage company or other lending business. PRIVATE:
                a trust, a seller carry-back or another private party, not the
                hard-money sense of private lender, which the Lender object
                carries as is_hard_money. INDIVIDUAL: a person's name.
                GOVERNMENT: an agency or a public body.
            - type: 'null'
          description: >-
            How that spelling reads. Null when the name is blank. How the lender
            name reads. BANK: a bank, credit union or thrift. NONBANK: a
            mortgage company or other lending business. PRIVATE: a trust, a
            seller carry-back or another private party, not the hard-money sense
            of private lender, which the Lender object carries as is_hard_money.
            INDIVIDUAL: a person's name. GOVERNMENT: an agency or a public body.
        identity_basis:
          anyOf:
            - type: string
              enum:
                - NAME_FOLD
                - TRUNCATED_PREFIX
                - ALIAS_DICTIONARY
              description: >-
                How the registry ties the spelling to its lender: NAME_FOLD
                means the folded name alone joins them. The fold uses upper
                case, drops punctuation and entity suffixes and spells out
                abbreviations: WELLS FARGO BANK NA and WELLS FARGO BANK N.A. are
                one. TRUNCATED_PREFIX: the file cut the name at 30 or 40
                characters, and the registry joined it to the one longer name
                that starts with it. ALIAS_DICTIONARY: a hand-kept row joined
                it, for a rename such as QUICKEN LOANS to ROCKET MORTGAGE, a
                trade name or a charter form. A row also covers a spelling the
                same instrument carries both ways. The registry never merges
                acquisitions.
            - type: 'null'
          description: >-
            How the registry tied that spelling to the lender. Null when the
            name is blank. How the registry ties the spelling to its lender:
            NAME_FOLD means the folded name alone joins them. The fold uses
            upper case, drops punctuation and entity suffixes and spells out
            abbreviations: WELLS FARGO BANK NA and WELLS FARGO BANK N.A. are
            one. TRUNCATED_PREFIX: the file cut the name at 30 or 40 characters,
            and the registry joined it to the one longer name that starts with
            it. ALIAS_DICTIONARY: a hand-kept row joined it, for a rename such
            as QUICKEN LOANS to ROCKET MORTGAGE, a trade name or a charter form.
            A row also covers a spelling the same instrument carries both ways.
            The registry never merges acquisitions.
        recording_date:
          anyOf:
            - type: string
              description: Calendar date, YYYY-MM-DD.
            - type: 'null'
          description: The recording date, YYYY-MM-DD. Null when the file carries none.
        due_date:
          anyOf:
            - type: string
              description: Calendar date, YYYY-MM-DD.
            - type: 'null'
          description: >-
            The maturity date, YYYY-MM-DD. Null when the file carries none, as
            on most hard-money rows.
        loan_amount:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
              description: Whole US dollars.
            - type: 'null'
          description: >-
            The original loan amount, whole dollars. Null when the file carries
            none.
        amount_outlier:
          description: >-
            True when loan_amount exceeds $5,000,000. Such an amount is a
            facility amount the file records on every parcel a commercial
            facility covers. The row keeps it, but the lender's volumes and
            amount quartiles leave it out, and n_amount_excluded_24m counts the
            excluded instruments. Null where loan_amount is null.
          type:
            - boolean
            - 'null'
        current_balance:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
              description: Whole US dollars.
            - type: 'null'
          description: >-
            The estimated current balance at `as_of`, whole dollars. Open rows
            only: null on recorded rows and where the file carries none.
        balance_outlier:
          description: >-
            True when current_balance exceeds $5,000,000. The lender's
            open_balance leaves such a balance out. Null where current_balance
            is null.
          type:
            - boolean
            - 'null'
        on_resold_parcel:
          description: >-
            True when the deeds show a sale of the parcel more than 30 days
            after this open row's recording. The loan is probably paid off, so
            open_balance leaves the row out. Null on recorded rows and where the
            market has no deed table.
          type:
            - boolean
            - 'null'
        interest_rate:
          description: >-
            The interest rate, percent as the file writes it. On open rows it is
            an estimate at `as_of`. On history rows it is the rate at recording.
            Null when not on file.
          type:
            - number
            - 'null'
        term_months:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
          description: The term in months as the file writes it. Null when not on file.
        term_band:
          type: string
          enum:
            - LE_24M
            - 25_TO_120M
            - 121_TO_359M
            - GE_360M
            - UNKNOWN
          description: >-
            The loan term in months, from the file's term where it carries one,
            else from the maturity date less the recording date. LE_24M: up to
            24 months, the bridge and fix-and-flip range. 25_TO_120M: 25 to 120
            months. 121_TO_359M: 121 to 359 months. GE_360M: 30 years and
            longer. UNKNOWN: neither a term nor a maturity on file, which is
            most hard-money rows.
        loan_type:
          description: >-
            The loan type as the file writes it, for example "New Conventional",
            "FHA" or "Credit Line (Revolving)". Null when blank or "Unknown
            (DEFAULT)".
          type:
            - string
            - 'null'
        label:
          anyOf:
            - type: string
              enum:
                - REFI_OR_SECOND
                - HELOC
                - RESALE_PURCHASE_MONEY
                - NEW_PURCHASE_MONEY
                - CONSTRUCTION
                - NON_RESIDENTIAL
              description: >-
                The file's transaction label, mapped to a closed list.
                REFI_OR_SECOND: refinance loans and second trust deeds, purchase
                and non-purchase money lumped together. RESALE_PURCHASE_MONEY: a
                purchase-money loan on a resale. NEW_PURCHASE_MONEY: a
                purchase-money loan on a new home. HELOC, CONSTRUCTION and
                NON_RESIDENTIAL: the file's label of that name. The purchase
                labels stop in January 2022, and a label never decides if a loan
                financed a purchase.
            - type: 'null'
          description: >-
            Null when the file's label is blank or unmapped, which it is on most
            open rows. The file's transaction label, mapped to a closed list.
            REFI_OR_SECOND: refinance loans and second trust deeds, purchase and
            non-purchase money lumped together. RESALE_PURCHASE_MONEY: a
            purchase-money loan on a resale. NEW_PURCHASE_MONEY: a
            purchase-money loan on a new home. HELOC, CONSTRUCTION and
            NON_RESIDENTIAL: the file's label of that name. The purchase labels
            stop in January 2022, and a label never decides if a loan financed a
            purchase.
        label_as_recorded:
          description: >-
            The file's transaction label as written, for example "Resale
            purchase money loans". Null when blank.
          type:
            - string
            - 'null'
        product:
          type: string
          enum:
            - CONSTRUCTION
            - HELOC
            - OTHER
          description: >-
            What the file says the loan is, read from its flags and loan type
            and never from the label. CONSTRUCTION: the construction flag or a
            "Building or Construction Loan" type. HELOC: the credit-line flag or
            a "Credit Line (Revolving)" type. OTHER: everything else, that is a
            purchase-money or refinance mortgage of any kind.
        product_proxy:
          anyOf:
            - type: string
              enum:
                - BRIDGE
                - RENTAL_TERM
                - RETAIL
              description: >-
                An inference from the term, not a fact the file states. BRIDGE:
                an OTHER product with a term of 24 months or less, a bridge or
                fix-and-flip loan. RENTAL_TERM: a term of 30 years or more from
                a hard-money lender, a DSCR rental loan. RETAIL: any other known
                term. Null when the term band is UNKNOWN.
            - type: 'null'
          description: >-
            Null when term_band is UNKNOWN. An inference from the term, not a
            fact the file states. BRIDGE: an OTHER product with a term of 24
            months or less, a bridge or fix-and-flip loan. RENTAL_TERM: a term
            of 30 years or more from a hard-money lender, a DSCR rental loan.
            RETAIL: any other known term. Null when the term band is UNKNOWN.
        product_basis:
          anyOf:
            - type: string
              enum:
                - FILE
                - TERM
              description: >-
                Where the term behind term_band and product_proxy comes from.
                FILE: the file's own term in months. TERM: the registry computed
                it from the maturity date less the recording date. Null when the
                term band is UNKNOWN.
            - type: 'null'
          description: >-
            Null when term_band is UNKNOWN. Where the term behind term_band and
            product_proxy comes from. FILE: the file's own term in months. TERM:
            the registry computed it from the maturity date less the recording
            date. Null when the term band is UNKNOWN.
        open_position:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
          description: >-
            The open lien position of the instrument. On an open row it is the
            row's own. On a recorded row in both tables it is the open twin's.
            Null on a recorded row with no open twin.
        assigned_lender_name:
          description: >-
            The lender the loan went to by assignment, as the file writes it.
            Open rows only. Null when the file records none.
          type:
            - string
            - 'null'
        blanket_group_id:
          description: >-
            32 hex characters that the open rows of one blanket loan share. A
            blanket loan has the same lender, date and amount on 5 or more
            parcels. The grouping leaves out credit lines and banks. Null
            outside a group.
          type:
            - string
            - 'null'
        blanket_n_parcels:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
          description: How many parcels the blanket group spans. Null outside a group.
        county_fips:
          description: >-
            The parcel's 5-digit county FIPS, for example 04013. Null when the
            parcel table carries none.
          type:
            - string
            - 'null'
        property_type_category:
          description: >-
            The parcel's property type category as the assessor feed writes it,
            for example "Residential". Null when not on file.
          type:
            - string
            - 'null'
        purpose:
          anyOf:
            - type: string
              enum:
                - PURCHASE
                - NOT_PURCHASE
                - UNKNOWN
              description: >-
                The loan's purpose, that is if it financed a purchase, read from
                the recorded deeds and never from the file's label. PURCHASE: a
                priced deed on the parcel, $10,000 or more, is dated in the 45
                days up to and including the recording date. A deed after the
                loan is a later sale, never this loan's purchase. NOT_PURCHASE:
                the deed registry covers those 45 days, the parcel has priced
                deeds, and none falls in them. Such a loan is a refinance, a
                second, a HELOC or a construction draw. UNKNOWN: the deed
                registry does not cover the window: its deeds or the parcel's
                deeds start after the loan, or the market has none.
            - type: 'null'
          description: >-
            Null on a registry built before the deed link. The loan's purpose,
            that is if it financed a purchase, read from the recorded deeds and
            never from the file's label. PURCHASE: a priced deed on the parcel,
            $10,000 or more, is dated in the 45 days up to and including the
            recording date. A deed after the loan is a later sale, never this
            loan's purchase. NOT_PURCHASE: the deed registry covers those 45
            days, the parcel has priced deeds, and none falls in them. Such a
            loan is a refinance, a second, a HELOC or a construction draw.
            UNKNOWN: the deed registry does not cover the window: its deeds or
            the parcel's deeds start after the loan, or the market has none.
        deed:
          anyOf:
            - $ref: '#/components/schemas/LenderLoanDeed'
            - type: 'null'
          description: >-
            The purchase deed the loan financed, on a PURCHASE row. Null on
            every other row.
        deal:
          anyOf:
            - $ref: '#/components/schemas/LenderLoanDeal'
            - type: 'null'
          description: >-
            The investor deal linked to the loan. The deal's purchase date is
            within 45 days before the recording, or under LOOSE from 15 days
            after to 90 days before. The loan is its purchase loan or a
            secondary. Null when the loan ties to no deal, and while the market
            has no deal link.
        outcome:
          anyOf:
            - type: string
              enum:
                - RESOLVED_BY_RESALE
                - REFINANCED
                - OPEN
                - FORECLOSED
                - UNKNOWN
              description: >-
                What became of a loan tied to a deal: a performance proxy read
                from the deed chain, never from a delinquency record or payment
                history. RESOLVED_BY_RESALE is a priced deed on the parcel after
                the loan, and REFINANCED is a later mortgage on it in either
                table before any resale. OPEN is an open lien position at the
                slice date and nothing later, and UNKNOWN is none of these
                because the chain runs out. FORECLOSED: a take-back deed on the
                parcel more than 90 days after the loan's recording, before any
                priced resale and any later mortgage. A take-back deed is a
                trustee's deed, a sheriff's deed or a deed in lieu, and the
                foreclosed block on the loan row carries it. A shorter gap is
                the auction buyer's own deed, not a foreclosure of this loan.
            - type: 'null'
          description: >-
            Null when deal is null. What became of a loan tied to a deal: a
            performance proxy read from the deed chain, never from a delinquency
            record or payment history. RESOLVED_BY_RESALE is a priced deed on
            the parcel after the loan, and REFINANCED is a later mortgage on it
            in either table before any resale. OPEN is an open lien position at
            the slice date and nothing later, and UNKNOWN is none of these
            because the chain runs out. FORECLOSED: a take-back deed on the
            parcel more than 90 days after the loan's recording, before any
            priced resale and any later mortgage. A take-back deed is a
            trustee's deed, a sheriff's deed or a deed in lieu, and the
            foreclosed block on the loan row carries it. A shorter gap is the
            auction buyer's own deed, not a foreclosure of this loan.
        months_to_resolution:
          description: >-
            Months from the recording date to the event that resolved the loan,
            1 decimal. The event is the resale deed, the refinancing mortgage or
            the take-back deed. Null unless outcome is RESOLVED_BY_RESALE,
            REFINANCED or FORECLOSED.
          type:
            - number
            - 'null'
        foreclosed:
          anyOf:
            - $ref: '#/components/schemas/LenderLoanForeclosed'
            - type: 'null'
          description: >-
            The earliest take-back deed on the parcel more than 90 days after
            the recording that precedes any resale or later mortgage. A
            take-back deed is a trustee's deed, a sheriff's deed or a deed in
            lieu. A shorter gap is the auction buyer's own deed, not a
            foreclosure of this loan. The flag buyer_is_lender is true when the
            grantee is this lender under any of its spellings. On a loan tied to
            a deal it is the FORECLOSED outcome. Null when none, and on a
            registry built before the take-back join: takebacks_measured false,
            or a registry built before the place rankings.
        investor_id:
          anyOf:
            - type: string
              pattern: ^inv_[0-9a-f]{12}$
              description: >-
                Investor id: inv_ followed by 12 hex characters, for example
                inv_abaf618f44a3. The id is stable across data refreshes within
                a market. Store it as the investor's identity.
            - type: 'null'
          description: >-
            The registered investor the borrowers resolve to, the key to GET
            `/v1/investors/{id}`. When the borrowers resolve to several
            investors, the field carries the one with the most deals. Null when
            no borrower resolves to one, and while the market has no borrower
            match.
        co_borrower_investor_ids:
          anyOf:
            - type: array
              items:
                type: string
                pattern: ^inv_[0-9a-f]{12}$
                description: >-
                  Investor id: inv_ followed by 12 hex characters, for example
                  inv_abaf618f44a3. The id is stable across data refreshes
                  within a market. Store it as the investor's identity.
            - type: 'null'
          description: >-
            The other registered investors the borrowers resolve to, most deals
            first. Empty when none. Null with borrower_keys.
        borrower_keys:
          anyOf:
            - type: array
              items:
                type: string
                pattern: ^[0-9a-f]{12}$
                description: >-
                  Borrower key: 12 hex characters hashed from the borrower's
                  folded name with the dataset salt. The same key appears on
                  every lender's rows and in every market. It is not a name and
                  not reversible, and it is stable across data refreshes. Use
                  the key to compare borrowers across lenders.
            - type: 'null'
          description: >-
            The borrowers' keys, one per name the recorded mortgage carries, in
            the file's order. On an open lien that names none, one key for the
            owner of record. These are the keys to GET
            `/v1/lenders/{id}/borrowers`. They are not names, and the API serves
            them to every key. Null when the row has no borrower source, that is
            an open lien naming none whose owner does not qualify. Null also on
            a registry built before the borrower match.
        borrower_match:
          anyOf:
            - type: string
              enum:
                - DEAL
                - ENTITY_NAME
                - PERSON_NAME
                - PARTY
                - MORTGAGE_ONLY
                - OWNER_OF_RECORD
              description: >-
                How the registry resolved the borrower, by the first rule that
                applied. DEAL: the loan has a deal whose investor has a member
                with the borrower's key, or the deal's investor when no key
                matched. ENTITY_NAME: the key is an entity member of exactly one
                investor, and PERSON_NAME means a person member of exactly one
                investor. PARTY: the key is on a recorded deed but belongs to no
                investor, while MORTGAGE_ONLY means the key is on no deed.
                OWNER_OF_RECORD: an open lien that names no borrower resolves to
                the parcel's owner of record. The registry takes the owner only
                when the owner held the parcel on the recording date and no sale
                followed.
            - type: 'null'
          description: >-
            Null with borrower_keys. How the registry resolved the borrower, by
            the first rule that applied. DEAL: the loan has a deal whose
            investor has a member with the borrower's key, or the deal's
            investor when no key matched. ENTITY_NAME: the key is an entity
            member of exactly one investor, and PERSON_NAME means a person
            member of exactly one investor. PARTY: the key is on a recorded deed
            but belongs to no investor, while MORTGAGE_ONLY means the key is on
            no deed. OWNER_OF_RECORD: an open lien that names no borrower
            resolves to the parcel's owner of record. The registry takes the
            owner only when the owner held the parcel on the recording date and
            no sale followed.
        as_of:
          type: string
          description: >-
            The slice date, YYYY-MM-DD. The API reads the row at it. Dated: see
            meta.dated[].
        dated:
          type: boolean
          description: >-
            True while the datasets are not in the current delivery, so the row
            is a snapshot at as_of.
      required:
        - market
        - property_id
        - address_short
        - city
        - zip
        - source
        - position
        - loan_key
        - in_both
        - lender_id
        - lender_id_open
        - lender_disagrees
        - lender_name_as_recorded
        - lender_class
        - identity_basis
        - recording_date
        - due_date
        - loan_amount
        - amount_outlier
        - current_balance
        - balance_outlier
        - on_resold_parcel
        - interest_rate
        - term_months
        - term_band
        - loan_type
        - label
        - label_as_recorded
        - product
        - product_proxy
        - product_basis
        - open_position
        - assigned_lender_name
        - blanket_group_id
        - blanket_n_parcels
        - county_fips
        - property_type_category
        - purpose
        - deed
        - deal
        - outcome
        - months_to_resolution
        - foreclosed
        - investor_id
        - co_borrower_investor_ids
        - borrower_keys
        - borrower_match
        - as_of
        - dated
      additionalProperties: false
      description: >-
        One loan of the lender. The row carries the parcel, which table the row
        comes from and if the other table has it too, and the lender as
        recorded. It carries the amount, balance, rate, term and maturity as the
        file carries them, and the product, term band and label read from them.
        It says if the loan financed a purchase and which deed, and names the
        investor deal linked to it and what became of it. It also carries the
        borrowers as keys and the investor they resolve to.
    Page:
      type: object
      properties:
        next_cursor:
          description: >-
            Opaque cursor for the next page: pass it back as cursor= with the
            same query. Null on the last page.
          type:
            - string
            - 'null'
        limit:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: The page size the API applied.
        returned:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: Rows in this page.
      required:
        - next_cursor
        - limit
        - returned
      additionalProperties: false
      description: >-
        Pagination: the page size, the rows returned and the cursor for the next
        page. Paged lists carry no total. The summary block does.
    Meta:
      type: object
      properties:
        generated_at:
          type: string
          description: >-
            When the API produced this response, ISO 8601. It does not change
            the ETag.
        weights:
          description: >-
            The effective match weights, one per factor, rounded to 4 decimals
            (buyers/match only). The API rescales the weights of the scored
            factors to sum 1 before it reports them.
          type: object
          propertyNames:
            type: string
          additionalProperties:
            type: number
        reference_point:
          description: >-
            The point the API measures every distance in the response from: lat
            + lng, or the centre of the property_id parcel. Absent with a bare
            bbox.
          type: object
          properties:
            lat:
              type: number
              minimum: -90
              maximum: 90
              description: Latitude of the reference point.
            lng:
              type: number
              minimum: -180
              maximum: 180
              description: Longitude of the reference point.
          required:
            - lat
            - lng
          additionalProperties: false
        geometry:
          $ref: '#/components/schemas/MetaGeometry'
          description: >-
            The location that ran, defaults filled and keyed as the query is
            (see MetaGeometry), on REST only: the MCP meta carries
            reference_point alone. Present on every route that takes a location:
            the deal lists, summary and cells, the investors, wholesale listings
            and short-term rental parcels, and `/v1/buyers/match`. Also on the
            comps of a parcel, kind radius around the subject and property_id
            the subject, and on POST `/v1/properties/search` (a county-only body
            echoes nothing). The lender list and a lender's loans carry it when
            you gave a geometry, a zip or a city. They apply a geometry as the
            H3 res-8 cells whose centre lies inside it, and echo no county,
            because MetaGeometry has no county slot. Absent on a route with no
            location, and on `/v1/properties/resolve`, whose lat + lng is a hint
            for the nearest parcel, not an area that ran.
        resolved_from:
          description: >-
            Present when an id in the request was an old id from an earlier data
            refresh: the old ids the API followed, in order. The ids are the
            investor id, from the path or the investor_id filter, the agent id
            and the lender id. The lender id comes from the path of the lender
            routes, the financed_by filter or filters.financing.lender_id. Store
            the id the response carries, not the old one.
          type: array
          items:
            type: string
            pattern: ^(inv|agt|len)_[0-9a-f]{12}$
            description: >-
              An investor id (inv_...), a listing agent id (agt_...) or a lender
              id (len_...).
        coverage:
          type: array
          items:
            $ref: '#/components/schemas/Coverage'
          description: >-
            The markets the response draws on, with their counties, data end
            dates and data versions.
        dated:
          description: >-
            Present when the response carries a block that is a dated snapshot
            at its as-of date, not current data. Those blocks are the financing,
            lien and valuation blocks of the parcel products. One entry per
            dated block, with its as-of date. Absent when nothing in the
            response is dated.
          type: array
          items:
            $ref: '#/components/schemas/Dated'
        terms:
          type: string
          description: Attribution and data-use terms for the data in this response.
      required:
        - generated_at
        - coverage
        - terms
      additionalProperties: false
      description: >-
        Response metadata: when the API produced it, which markets it covers,
        and how fresh they are.
    Problem:
      type: object
      properties:
        type:
          type: string
          description: >-
            URI of the problem: the Errors page of the documentation site,
            anchored at the code.
        title:
          type: string
          description: Short human-readable summary of the problem code.
        status:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: HTTP status.
        code:
          type: string
          description: >-
            Stable machine-readable code from the catalogue at
            https://developers.investorlift.com/problems.json.
        detail:
          type: string
          description: Human-readable explanation specific to this occurrence.
        instance:
          type: string
          description: Request path.
        request_id:
          type: string
          description: Request id to quote when you report a problem.
        errors:
          description: Per-parameter validation failures (400 only).
          type: array
          items:
            type: object
            properties:
              param:
                description: >-
                  The offending parameter. Null when the problem is not about
                  one parameter.
                type:
                  - string
                  - 'null'
              message:
                type: string
                description: What is wrong with it.
              code:
                type: string
                description: Machine-readable reason, for example invalid_enum_value.
            required:
              - param
              - message
              - code
            additionalProperties: false
            description: One validation failure.
      required:
        - type
        - title
        - status
        - code
        - detail
        - instance
        - request_id
      additionalProperties: {}
      description: >-
        RFC 9457 problem details (application/problem+json). Some codes add
        extra fields beside these: superseded_by, candidates, n_deals, cap,
        suggestion, markets, retry_after.
    LenderLoanDeed:
      type: object
      properties:
        dt:
          type: string
          description: >-
            The date of the purchase deed the loan financed, YYYY-MM-DD. That
            deed is the priced deed on the parcel dated in the 45 days up to and
            including the recording date.
        price:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: >-
            The price on that deed, whole dollars. It is $10,000 or more, the
            pairing floor.
        loan_to_price:
          anyOf:
            - type: number
              description: Decimal ratio, never a percentage (0.53 = +53%).
            - type: 'null'
          description: >-
            loan_amount divided by price, 4 decimals, for example 1.12. A ratio
            above 1 is a rehab holdback on top of the price, not an error. Null
            when the loan carries no amount. Null also when the ratio is above 3
            without a blanket group: that is a facility amount, not a loan on
            this parcel.
      required:
        - dt
        - price
        - loan_to_price
      additionalProperties: false
      description: >-
        The purchase deed a purchase-money loan financed: its date, its price
        and the loan against it.
    LenderLoanDeal:
      type: object
      properties:
        deal_id:
          type: string
          pattern: ^deal_[0-9a-f]{32}$
          description: 'The deal: the key to GET `/v1/deals/{deal_id}`.'
        kind:
          type: string
          enum:
            - flip
            - wholesale
            - hold
            - long_hold
            - other
            - build
          description: >-
            What occurred on the deal. flip: bought, fixed and resold within
            about a year at a profit-shaped margin; wholesale: bought and resold
            in under 30 days, or a chain resale or round trip within 90 (a
            double close); hold: bought and still owned at data_end, a confirmed
            holding or an un-resold purchase; long_hold: held over a year, then
            sold (a landlord exit); other: an investor resale that is not a
            clean flip. Reasons: a loss, a thin margin, a builder's new home
            resold, an iBuyer resale, or a chain resale of 3 to 12 months;
            build: a registered investor bought a lot or teardown, built a house
            on it during the hold, then sold. A builder's finished home bought
            and resold is other. On data built after 2026-09-17 the kind keeps
            only a single-family parcel held over 90 days, its house complete by
            the sale year. A market built on or before 2026-09-17
            (meta.coverage[].loaded_at) counts every lot-to-build resale by a
            registered investor as a build until its next build.
        link_window:
          type: string
          enum:
            - STRICT
            - LOOSE
          description: >-
            How the registry tied the loan to its deal. STRICT: the recording
            date falls in the 45 days from the purchase date, the window every
            count uses. LOOSE: the recording date falls from 15 days before to
            90 days after the purchase date. The row keeps a LOOSE link for
            reading, but no count uses it, and the registry never applies it to
            a wholesale deal.
        is_purchase_loan:
          type: boolean
          description: >-
            True when this is the deal's purchase loan: the largest amount among
            the loans recorded in the window, then the earliest, then the lowest
            position. False on the others, which secondary_loans_n on the
            purchase loan counts. Every count of the profile reads the purchase
            loan alone.
        secondary_loans_n:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
          description: >-
            On the purchase loan, how many other loans have a recording date in
            the deal's window, for example a second or a rehab draw. Null on a
            secondary loan.
        investor_id:
          anyOf:
            - type: string
              pattern: ^inv_[0-9a-f]{12}$
              description: >-
                Investor id: inv_ followed by 12 hex characters, for example
                inv_abaf618f44a3. The id is stable across data refreshes within
                a market. Store it as the investor's identity.
            - type: 'null'
          description: >-
            The deal's buyer when it is a registered investor. Null otherwise.
            The loan row's own investor_id is the borrower's, which is the same
            on a DEAL match.
        investor_name:
          description: >-
            That investor's registry name, the deed spelling, upper case,
            SURNAME GIVEN for a person, as the registry serves it. The API
            serves it to every key. Null when investor_id is null.
          type:
            - string
            - 'null'
        investor_display_name:
          description: >-
            That investor's name to print (API 0.32.0): GIVEN [MIDDLE] SURNAME
            [SUFFIX] for a person whose deed spelling parsed cleanly, equal to
            investor_name otherwise. Null exactly when investor_name is null.
            Display only.
          type:
            - string
            - 'null'
        bought_on:
          anyOf:
            - type: string
              description: Calendar date, YYYY-MM-DD.
            - type: 'null'
          description: The deal's purchase date, YYYY-MM-DD.
        bought_price:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
              description: Whole US dollars.
            - type: 'null'
          description: >-
            What the investor paid, whole dollars. Null when the deed carries no
            price.
        sold_on:
          anyOf:
            - type: string
              description: Calendar date, YYYY-MM-DD.
            - type: 'null'
          description: >-
            The resale date, YYYY-MM-DD. Null while the investor still holds the
            parcel at the market's data_end.
        sold_price:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
              description: Whole US dollars.
            - type: 'null'
          description: >-
            The resale price, whole dollars. Null while the investor still holds
            the parcel at the market's data_end, and null when the resale deed
            carries no price.
        gross_profit:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
              description: Whole US dollars.
            - type: 'null'
          description: >-
            sold_price less bought_price on a resold deal with both prices,
            whole dollars. Null otherwise. Not net of rehab or costs.
        hold_days:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
          description: >-
            Days from purchase to resale. Null while the investor still holds
            the parcel at the market's data_end.
      required:
        - deal_id
        - kind
        - link_window
        - is_purchase_loan
        - secondary_loans_n
        - investor_id
        - investor_name
        - investor_display_name
        - bought_on
        - bought_price
        - sold_on
        - sold_price
        - gross_profit
        - hold_days
      additionalProperties: false
      description: >-
        The investor deal linked to the loan: which deal, if this loan is its
        purchase loan, who bought, and the outcome the deeds show.
    LenderLoanForeclosed:
      type: object
      properties:
        instrument:
          type: string
          enum:
            - TRUSTEES_DEED
            - SHERIFFS_DEED
            - DEED_IN_LIEU
          description: >-
            The deed by which a lender took a property back. TRUSTEES_DEED: a
            trustee's deed after a non-judicial foreclosure sale, the
            certificate of title in Arizona. SHERIFFS_DEED: a sheriff's deed
            after a judicial sale, in an Arizona or Washington market. In Texas
            a sheriff's deed is a tax sale, never a take-back. DEED_IN_LIEU: the
            borrower deeded the property to the lender instead of a foreclosure.
        deed_date:
          type: string
          description: >-
            The date of the take-back deed, YYYY-MM-DD. That deed is the
            earliest take-back deed on the parcel more than 90 days after the
            recording date. It also precedes any priced resale and any later
            mortgage of another lender. A shorter gap is the auction buyer's own
            deed, not a foreclosure of this loan.
        buyer_is_lender:
          type: boolean
          description: >-
            True when the grantee of the take-back deed is this lender under any
            of its spellings. False when the grantee is another party: the
            trustee, the servicer or another lender named on the deed.
      required:
        - instrument
        - deed_date
        - buyer_is_lender
      additionalProperties: false
      description: >-
        The take-back deed that followed the loan on its parcel: the instrument,
        its date and if this lender was the grantee. The event behind the
        FORECLOSED outcome of a captured loan.
    MetaGeometry:
      type: object
      properties:
        kind:
          type: string
          enum:
            - radius
            - bbox
            - place
          description: >-
            Which location ran: radius, bbox or place. A radius is a point with
            radius_miles, or a property_id request, which runs around the parcel
            centroid. A bbox is a viewport. A place is a ZIP list or a postal
            city.
        lat:
          anyOf:
            - type: number
              minimum: -90
              maximum: 90
              description: WGS84 latitude.
            - type: 'null'
          description: >-
            The centre of the radius, or the reference point you gave beside a
            bbox or a place. For a property_id request the centre is the parcel
            centroid. Null when a bbox or a place had no reference point.
        lng:
          anyOf:
            - type: number
              minimum: -180
              maximum: 180
              description: WGS84 longitude.
            - type: 'null'
          description: The longitude beside lat. Null when lat is null.
        radius_miles:
          description: >-
            The radius that ran, in miles: the value you sent, or the default
            when you sent none. The default is 2 on the GET lists and 1 around
            property_id on POST `/v1/properties/search`. Null for a bbox or a
            place.
          type:
            - number
            - 'null'
        bbox:
          anyOf:
            - type: array
              prefixItems:
                - type: number
                  minimum: -180
                  maximum: 180
                  description: West edge (longitude).
                - type: number
                  minimum: -90
                  maximum: 90
                  description: South edge (latitude).
                - type: number
                  minimum: -180
                  maximum: 180
                  description: East edge (longitude).
                - type: number
                  minimum: -90
                  maximum: 90
                  description: North edge (latitude).
              items: false
              minItems: 4
              maxItems: 4
              description: '[west, south, east, north] in WGS84 degrees.'
            - type: 'null'
          description: >-
            The viewport as [west, south, east, north] in WGS84 degrees. Null
            unless kind is bbox.
        property_id:
          anyOf:
            - type: string
              pattern: ^prop_[0-9a-f]{32}$
              description: >-
                Parcel id: prop_ followed by 32 hex characters, for example
                prop_e93c776c53354a88de4e58448a6bf21b. The prefix is part of the
                id.
            - type: 'null'
          description: >-
            The parcel at the centre of the radius. Null unless the request
            named property_id.
        zip:
          anyOf:
            - type: array
              items:
                type: string
                pattern: ^\d{5}$
            - type: 'null'
          description: >-
            The ZIP list as you sent it, for example ["85251", "85257"]. Null
            unless kind is place and the request named ZIPs.
        city:
          description: >-
            The postal city as the API compared it: trimmed and folded to upper
            case ("Scottsdale" ran as "SCOTTSDALE"). Null unless kind is place
            and the request named a city.
          type:
            - string
            - 'null'
      required:
        - kind
        - lat
        - lng
        - radius_miles
        - bbox
        - property_id
        - zip
        - city
      additionalProperties: false
      description: >-
        The location the API computed the response over, as it ran: defaults
        filled, a parcel resolved to its centroid, a city folded. Copy it back
        as the query to repeat the request.
    Coverage:
      type: object
      properties:
        market:
          type: string
          description: Market code, for example phx. One entry per loaded market.
        state:
          type: string
          description: >-
            2-letter state of the market. The loaded markets and their states
            are in meta.coverage[].
        counties:
          type: array
          items:
            type: object
            properties:
              fips:
                type: string
                description: The 5-digit county FIPS code, for example 04013.
              name:
                type: string
                description: County name, for example Maricopa.
              data_end:
                anyOf:
                  - type: string
                    description: Calendar date, YYYY-MM-DD.
                  - type: 'null'
                description: >-
                  The last deed date on file for this county, YYYY-MM-DD. Null
                  when the county carries no dated deed.
            required:
              - fips
              - name
              - data_end
            additionalProperties: false
            description: One county the loaded area lies in.
          description: >-
            The counties the loaded area lies in, each with its own data end
            date. For a zip market the list names the county, but the loaded
            area is only the ZIP (see universe_kind).
        bbox:
          type: array
          prefixItems:
            - type: number
              minimum: -180
              maximum: 180
              description: West edge (longitude).
            - type: number
              minimum: -90
              maximum: 90
              description: South edge (latitude).
            - type: number
              minimum: -180
              maximum: 180
              description: East edge (longitude).
            - type: number
              minimum: -90
              maximum: 90
              description: North edge (latitude).
          items: false
          minItems: 4
          maxItems: 4
          description: >-
            The rectangle (west, south, east, north) that encloses every deal in
            the market: the initial map viewport and, with
            point_tolerance_miles, the limit for outside_coverage.
        data_end:
          type: string
          description: >-
            The last deed date in the data, YYYY-MM-DD. The API measures every
            "days since" value from this data_end, never from the request time.
        build_run_id:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
          description: >-
            Which pipeline build produced the data. Informational: use
            dataset_version for caching. Null when the data does not record it.
        registry_run:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
          description: >-
            Which investor registry run produced the data. Informational: use
            dataset_version for caching. Null when the data does not record it.
        registry_version:
          description: >-
            Which registry code version produced the data. Informational: use
            dataset_version for caching. Null when the data does not record it.
          type:
            - string
            - 'null'
        dataset_version:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: >-
            Version of the loaded data, an integer that grows with every
            refresh. It is the cache key and the ETag, and every cursor binds to
            it.
        loaded_at:
          type: string
          description: When this data version went live, ISO 8601.
        metro_buy_to_resale_ratio:
          anyOf:
            - type: number
              description: Decimal ratio, never a percentage (0.53 = +53%).
            - type: 'null'
          description: >-
            The median of purchase price divided by resale price over the
            market's priced flips since 2021. For example, 0.72 means flippers
            pay about 72% of the resale price. The price_fit factor uses it when
            an investor has too few flips of their own. Null when no priced
            flips exist.
        universe_kind:
          anyOf:
            - type: string
              enum:
                - zip
                - county
                - metro
              description: >-
                The area every count in this market covers: metro, county or
                zip. A metro market covers whole counties. A county market
                covers one county. The market cannot see what an investor did in
                the neighbouring counties. A zip market covers one or more ZIP
                codes. The market cannot see what an investor did outside them,
                a larger gap. In a county or zip market every investor count,
                price band, scale tier and confidence is a floor.
            - type: 'null'
          description: >-
            Null when the market row does not record it, a seed older than the
            column. The area every count in this market covers: metro, county or
            zip. A metro market covers whole counties. A county market covers
            one county. The market cannot see what an investor did in the
            neighbouring counties. A zip market covers one or more ZIP codes.
            The market cannot see what an investor did outside them, a larger
            gap. In a county or zip market every investor count, price band,
            scale tier and confidence is a floor.
        universe_zips:
          anyOf:
            - type: array
              items:
                type: string
                description: A 5-digit ZIP.
            - type: 'null'
          description: >-
            The ZIP codes of a zip universe, for example ["77088"]. Null for
            county and metro markets.
        point_tolerance_miles:
          type: number
          description: >-
            How far outside bbox a point can lie and get an answer, in miles: 20
            for a metro, 2 for a county market. The point is lat + lng, or the
            centre of a property_id parcel. Farther out, the API answers 422
            outside_coverage. A bbox must intersect the coverage bbox.
        n_parcels:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
          description: >-
            Parcels in the loaded area, the universe every count covers. Null
            when the data does not record it.
        listings_data_end:
          anyOf:
            - type: string
              description: Calendar date, YYYY-MM-DD.
            - type: 'null'
          description: >-
            The as-of date of the MLS listing feed for this market, YYYY-MM-DD:
            the newest status update among its listing rows, later than
            data_end. The deeds and the listings arrive in one delivery, each
            with its own end. The API measures every listing window
            (days_on_market, n_listed_12m) against this date. Null when this
            market has no published listing tables. Every listing block and
            listings rollup is null then, and the correct reading is "no listing
            data".
        agents_data_end:
          anyOf:
            - type: string
              description: Calendar date, YYYY-MM-DD.
            - type: 'null'
          description: >-
            The as-of date of the listing set behind the agent registry of this
            market, YYYY-MM-DD. It equals listings_data_end when the registry is
            current. It is earlier when a refresh moved the listings but left
            the agents on the older set. Null when this market has no published
            agent tables. Then every agent_id, identity_basis and
            agent_is_holder_member on the listing agents is null, and the
            investor profile carries has_licensed_member and agent_links null.
            The /v1/agents routes then answer 422 agents_unavailable.
        wholesale_as_of:
          anyOf:
            - type: string
              description: Calendar date, YYYY-MM-DD.
            - type: 'null'
          description: >-
            The date of the Investorlift export behind the market's wholesale
            transactions, YYYY-MM-DD. Every Investorlift listing published up to
            this date is on file. The API measures every wholesale window
            (n_listed_12m, n_bought_via_investorlift_12m) against the deed
            data_end. Null when this market has no published wholesale tables.
            Then every wholesale_listing block on deal rows, wholesale_purchases
            block on investor rows and wholesale_listings[] on a parcel is null.
            Then /v1/wholesale-listings, /v1/wholesalers,
            `/v1/investors/{id}/wholesale-purchases` and the source=investorlift
            and bought_on_investorlift filters answer 422 wholesale_unavailable.
        str_as_of:
          anyOf:
            - type: string
              description: Calendar date, YYYY-MM-DD.
            - type: 'null'
          description: >-
            The short-term rental snapshot of this market, YYYY-MM-DD: the
            oldest snapshot date among its served jurisdictions. Each
            jurisdiction's own date is in str.jurisdictions[].snapshot_date and
            on every block as data_as_of. Null when this market has no published
            short-term rental tables, or when the API serves none of its
            jurisdictions. Then every short_term_rental block on parcels and
            hold rows and every str roll-up on investor rows is null. Then the
            str_status, str_business_use, str_operator and str_holdings_min
            filters and /v1/str-parcels answer 422 str_unavailable.
        str:
          anyOf:
            - type: object
              properties:
                jurisdictions:
                  type: array
                  items:
                    $ref: '#/components/schemas/StrCoverageJurisdiction'
                  description: >-
                    Every city of the market the short-term rental build knows,
                    served or not. This list, not the parcel, explains a null
                    block on a parcel: read the city's coverage_reason.
              required:
                - jurisdictions
              additionalProperties: false
            - type: 'null'
          description: >-
            The short-term rental jurisdiction table of this market. Null when
            this market has no published short-term rental tables.
        auction_counted:
          type: boolean
          description: >-
            True when this market measures the foreclosure-auction and REO
            purchase counts. Then every investor row carries the auction block
            (investor.auction) and deal rows carry bought_auction_kind. False
            when the market's registry build came before the counts existed.
            Then the block is null on every investor of the market, and
            bought_auction_kind is null on every deal. The buys_at_auction,
            buys_reo and bought_auction_kind filters then answer 422
            auction_unavailable.
        parcel_as_of:
          anyOf:
            - type: string
              description: Calendar date, YYYY-MM-DD.
            - type: 'null'
          description: >-
            The deed data end that the build of the parcel product layer used,
            YYYY-MM-DD. The layer serves POST /v1/properties/search and the
            financing, permit and history routes. Null when this market has no
            published parcel product tables: those routes then answer 422
            parcels_unavailable.
        address_as_of:
          anyOf:
            - type: string
              description: Calendar date, YYYY-MM-DD.
            - type: 'null'
          description: >-
            The deed data end of the address table behind GET
            /v1/properties/resolve?address, YYYY-MM-DD. Null when this market
            has no published address table. The address lookup answers 422
            addresses_unavailable while no market carries the table.
        parcel:
          anyOf:
            - $ref: '#/components/schemas/ParcelCoverage'
            - type: 'null'
          description: >-
            What the parcel products cover in this market. The parts are the
            layer, the dated financing slice, the permit snapshot, the Owner
            Profile block and the history lake with its ZIP set. Null when this
            market has no published parcel product tables.
        lenders:
          anyOf:
            - type: object
              properties:
                as_of:
                  anyOf:
                    - type: string
                      description: Calendar date, YYYY-MM-DD.
                    - type: 'null'
                  description: >-
                    The slice date behind the lender registry, YYYY-MM-DD. It
                    equals parcel.financing.as_of.
                recordings_through:
                  anyOf:
                    - type: string
                      description: Calendar date, YYYY-MM-DD.
                    - type: 'null'
                  description: >-
                    The newest recording date in either source table,
                    YYYY-MM-DD. The API measures every recency on a lender
                    against this date.
                counties:
                  type: array
                  items:
                    type: string
                    description: A 5-digit county FIPS.
                  description: >-
                    The counties the lender registry covers. A ZIP, city or
                    county outside them answers 422 outside_coverage.
                history_capture_share:
                  anyOf:
                    - type: number
                      description: Decimal ratio, never a percentage (0.53 = +53%).
                    - type: 'null'
                  description: >-
                    The share of open lien positions recorded since 2022 that
                    the recorded history also carries within 3 days, 0 to 1. It
                    says how much of the open table the history sees.
                n_lender_ids:
                  anyOf:
                    - type: integer
                      minimum: -9007199254740991
                      maximum: 9007199254740991
                    - type: 'null'
                  description: >-
                    Lender ids served in the market: the identities with a
                    profile, after the person gate. parcel.financing.n_lenders
                    counts raw spellings, several per id.
                purchase_measured:
                  type: boolean
                  description: >-
                    True when the market has the deed link. Then the API serves
                    purpose and the deed block on the loan rows, and the
                    purchase-money counts and ranks on the lenders. It also
                    serves the lender list's purpose, investor_only and
                    purchase_desc parameters. False on a registry built before
                    the deed link: every such value is null, and those
                    parameters answer 422 lenders_unavailable.
                investor_lending_measured:
                  type: boolean
                  description: >-
                    True when the market has the deal link and the borrower
                    match. Then the API serves the deal block, outcome and
                    investor ids on the loan rows, and the investor_lending
                    block on the profiles. It also serves the financing block on
                    deal rows and the financing sidecar on investor profiles.
                    False otherwise: every one of those is null.
                flips_measured:
                  type: boolean
                  description: >-
                    True when the market measures the flips each lender
                    financed, the flips_financed block on the profiles. False
                    otherwise: the block is null.
                borrowers_measured:
                  type: boolean
                  description: >-
                    True when the market has the borrower fold. Then the API
                    serves borrower keys on the loan rows, the borrowers block
                    on the profiles, GET `/v1/lenders/{id}/borrowers` and the
                    financed_by and uses_private_lender filters. False
                    otherwise: the block is null, and the route and the filters
                    answer 422 lenders_unavailable.
                takebacks_measured:
                  type: boolean
                  description: >-
                    True when the registry of this market includes the
                    foreclosure take-backs. That needs the auction deed tables
                    built and the lender members present. Then the API serves
                    the takebacks block on the profiles, the foreclosed block on
                    the loan rows and the FORECLOSED outcome. False otherwise:
                    the block is null on every profile, and foreclosed is null
                    on every loan row.
                counties_measured:
                  type: boolean
                  description: >-
                    True when the market has more than one loaded county, so a
                    county ranking means something:
                    rankings.n_counties_ranked_first_24m on the profiles. False
                    while the slice covers one county: that count is null.
                dated:
                  description: >-
                    True when the registry is a snapshot valued at as_of, like
                    the financing slice behind it. The API stamps every value
                    from it in meta.dated[] as the lenders block. Null on a
                    registry row that does not record it, a row older than the
                    column.
                  type:
                    - boolean
                    - 'null'
                n_parcels_uncovered:
                  anyOf:
                    - type: integer
                      minimum: -9007199254740991
                      maximum: 9007199254740991
                    - type: 'null'
                  description: >-
                    Parcels of the market outside the counties the registry
                    covers. Such a county is one the financing slice does not
                    reach. Null when the row does not record it.
              required:
                - as_of
                - recordings_through
                - counties
                - history_capture_share
                - n_lender_ids
                - purchase_measured
                - investor_lending_measured
                - flips_measured
                - borrowers_measured
                - takebacks_measured
                - counties_measured
                - dated
                - n_parcels_uncovered
              additionalProperties: false
            - type: 'null'
          description: >-
            The lender registry of this market. Null when this market has no
            published lender tables: every /v1/lenders route then answers 422
            lenders_unavailable.
      required:
        - market
        - state
        - counties
        - bbox
        - data_end
        - build_run_id
        - registry_run
        - registry_version
        - dataset_version
        - loaded_at
        - metro_buy_to_resale_ratio
        - universe_kind
        - universe_zips
        - point_tolerance_miles
        - n_parcels
        - listings_data_end
        - agents_data_end
        - wholesale_as_of
        - str_as_of
        - str
        - auction_counted
        - parcel_as_of
        - address_as_of
        - parcel
        - lenders
      additionalProperties: false
      description: >-
        One loaded market: the area its counts cover (universe_kind), the
        counties it lies in, how fresh it is, and its data version.
    Dated:
      type: object
      properties:
        block:
          type: string
          enum:
            - valuation
            - financing
            - liens
            - lenders
          description: >-
            The block of the response that is a snapshot at as_of, not current
            data. The values are valuation (the AVM, equity and LTV), financing
            (open liens and mortgage history), liens (involuntary liens) and
            lenders. The lenders block is the lender registry and every count on
            it, built from the same slice.
        as_of:
          type: string
          description: >-
            The date of the delivery that valued the snapshot, YYYY-MM-DD: the
            same date as meta.coverage[].parcel.financing.as_of for the market.
        reason:
          type: string
          description: >-
            Why the block is dated, in one sentence: the dataset is not in the
            current delivery.
      required:
        - block
        - as_of
        - reason
      additionalProperties: false
      description: >-
        One block of the response that is a dated snapshot. Every response that
        carries a value from a dated block lists it here. A caller that cannot
        use dated data passes require_current: true. The API then answers 422
        dated_refused instead.
    StrCoverageJurisdiction:
      type: object
      properties:
        name:
          type: string
          description: >-
            The jurisdiction, upper case, for example SCOTTSDALE, PHOENIX or
            HOUSTON: the city-limit polygon the parcel falls in, never the
            postal city. The same value as
            short_term_rental.coverage.jurisdiction on the parcels inside it.
        regime:
          anyOf:
            - type: string
              enum:
                - REQUIRED
                - NOT_REQUIRED
                - UNKNOWN
              description: >-
                The city's rule on a short-term rental licence or permit.
                REQUIRED: an ordinance requires one. NOT_REQUIRED: the city has
                no requirement, so no roll exists. UNKNOWN: the survey did not
                cover the city. Null when the market row does not record it.
            - type: 'null'
          description: >-
            Null when the market row does not record it. The city's rule on a
            short-term rental licence or permit. REQUIRED: an ordinance requires
            one. NOT_REQUIRED: the city has no requirement, so no roll exists.
            UNKNOWN: the survey did not cover the city. Null when the market row
            does not record it.
        coverage_reason:
          anyOf:
            - type: string
              enum:
                - LOADED_SERVED
                - LOADED_UNVALIDATED
                - LOADED_COUNTS_ONLY
                - REQUIRED_NOT_PUBLISHED
                - NO_REQUIREMENT
                - NOT_SURVEYED
              description: >-
                Why parcels of this jurisdiction carry, or do not carry, a
                short-term rental block. LOADED_SERVED: the city's roll is on
                file, matched to parcels and served, so every parcel inside
                carries a block, NONE when it has no record. LOADED_UNVALIDATED:
                the roll is on file and matched, but without a spot check, so
                the block is present with status null and coverage.served false.
                LOADED_COUNTS_ONLY: the roll is on file for counts only, because
                no parcel match is possible for the file, so no block. No block
                for REQUIRED_NOT_PUBLISHED (licence required, no roll
                published), NO_REQUIREMENT (no licence required) or NOT_SURVEYED
                (outside the survey). Null when the market row does not record
                it.
            - type: 'null'
          description: >-
            Null when the market row does not record it. Why parcels of this
            jurisdiction carry, or do not carry, a short-term rental block.
            LOADED_SERVED: the city's roll is on file, matched to parcels and
            served, so every parcel inside carries a block, NONE when it has no
            record. LOADED_UNVALIDATED: the roll is on file and matched, but
            without a spot check, so the block is present with status null and
            coverage.served false. LOADED_COUNTS_ONLY: the roll is on file for
            counts only, because no parcel match is possible for the file, so no
            block. No block for REQUIRED_NOT_PUBLISHED (licence required, no
            roll published), NO_REQUIREMENT (no licence required) or
            NOT_SURVEYED (outside the survey). Null when the market row does not
            record it.
        served:
          type: boolean
          description: >-
            True when parcels inside this jurisdiction carry a measured status
            (LICENSED, PENDING, EXPIRED or NONE). False when they carry a block
            with status null, or no block at all: coverage_reason says why.
        snapshot_only:
          type: boolean
          description: >-
            True when the roll came from a single pull and has no weekly feed
            (Fountain Hills, Cave Creek). Its dates are the pull date, and the
            API never sets feed_stale.
        licence_start:
          anyOf:
            - type: string
              description: Calendar date, YYYY-MM-DD.
            - type: 'null'
          description: >-
            The earliest possible date of a licence in this jurisdiction, the
            day its ordinance took effect, YYYY-MM-DD, for example 2025-10-01
            for Houston. Null when unknown, or when the city requires no
            licence.
        snapshot_date:
          anyOf:
            - type: string
              description: Calendar date, YYYY-MM-DD.
            - type: 'null'
          description: >-
            The snapshot the served blocks read, YYYY-MM-DD:
            short_term_rental.data_as_of on every parcel inside. Null when no
            roll is on file.
        feed_stale:
          type: boolean
          description: >-
            True when this week's feed failed the freshness rule and the API
            serves the last good snapshot instead. Every block inside then
            carries coverage.feed_stale true. False otherwise.
        sources:
          type: array
          items:
            $ref: '#/components/schemas/StrCoverageSource'
          description: >-
            The city files behind this jurisdiction, each with its newest load
            date and its stale flag. Empty when no roll is on file.
        n_licensed:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
          description: >-
            Parcels inside with status LICENSED on this snapshot. Null when no
            roll is on file.
        n_pending:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
          description: Parcels inside with status PENDING. Null when no roll is on file.
        n_expired:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
          description: Parcels inside with status EXPIRED. Null when no roll is on file.
        n_advertised:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
          description: >-
            Parcels the city lists as advertised without a licence, Scottsdale
            only. The API counts them and never serves them as a status. Null
            when the city publishes no such list.
        share_unmatched:
          anyOf:
            - type: number
              description: Decimal ratio, never a percentage (0.53 = +53%).
            - type: 'null'
          description: >-
            The share of the city's records that matched no parcel, 0 to 1, for
            example 0.04. Null when no roll is on file.
        share_assumed:
          anyOf:
            - type: number
              description: Decimal ratio, never a percentage (0.53 = +53%).
            - type: 'null'
          description: >-
            The share of attributed parcels with attribution_basis ASSUMED, 0 to
            1. ASSUMED means the attribution has no date, no name and no regime
            bound. Null when no roll is on file.
      required:
        - name
        - regime
        - coverage_reason
        - served
        - snapshot_only
        - licence_start
        - snapshot_date
        - feed_stale
        - sources
        - n_licensed
        - n_pending
        - n_expired
        - n_advertised
        - share_unmatched
        - share_assumed
      additionalProperties: false
      description: >-
        One city of the market in the short-term rental build. It says if the
        licence roll is on file and served, how fresh it is, and what it counts.
        It explains a null short_term_rental block on a parcel: the block is
        null where the API does not serve the jurisdiction.
    ParcelCoverage:
      type: object
      properties:
        parcel_as_of:
          anyOf:
            - type: string
              description: Calendar date, YYYY-MM-DD.
            - type: 'null'
          description: The deed data end that the parcel layer build used, YYYY-MM-DD.
        n_parcels:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
          description: Parcels in the layer for this market.
        sale_mortgage_measured:
          type: boolean
          description: >-
            True when the delivery records a purchase mortgage on at least one
            priced last sale in five of the market. Then cash_sale_proxy, the
            sale.cash_sale filter and the cash-buyer quicklist are measured.
            False below that bar, as in the 2026 deliveries, which carry the
            column empty. Then cash_sale_proxy is null on every parcel, and the
            filter and the quicklist answer 422 cash_sale_unavailable.
        financing:
          anyOf:
            - type: object
              properties:
                as_of:
                  anyOf:
                    - type: string
                      description: Calendar date, YYYY-MM-DD.
                    - type: 'null'
                  description: >-
                    The date of the delivery that valued the financing, lien and
                    valuation slice, YYYY-MM-DD.
                dated:
                  type: boolean
                  description: >-
                    True while the Recorder & Mortgage and AVM datasets are not
                    in the current delivery, so the slice stays at as_of. The
                    API then stamps every value from the slice in meta.dated[].
                dated_reason:
                  description: Why the slice is dated.
                  type:
                    - string
                    - 'null'
                n_parcels:
                  anyOf:
                    - type: integer
                      minimum: -9007199254740991
                      maximum: 9007199254740991
                    - type: 'null'
                  description: Parcels with a row in the slice.
                n_with_open_lien:
                  anyOf:
                    - type: integer
                      minimum: -9007199254740991
                      maximum: 9007199254740991
                    - type: 'null'
                  description: Parcels with at least one open lien at as_of.
                n_free_and_clear:
                  anyOf:
                    - type: integer
                      minimum: -9007199254740991
                      maximum: 9007199254740991
                    - type: 'null'
                  description: Parcels with zero open liens at as_of.
                n_avm:
                  anyOf:
                    - type: integer
                      minimum: -9007199254740991
                      maximum: 9007199254740991
                    - type: 'null'
                  description: Parcels with an AVM at as_of.
                n_involuntary:
                  anyOf:
                    - type: integer
                      minimum: -9007199254740991
                      maximum: 9007199254740991
                    - type: 'null'
                  description: Parcels with an involuntary lien at as_of.
                n_lenders:
                  anyOf:
                    - type: integer
                      minimum: -9007199254740991
                      maximum: 9007199254740991
                    - type: 'null'
                  description: >-
                    Distinct raw lender spellings over the two lien tables, not
                    registry ids. For registry ids, read
                    meta.coverage[].lenders.n_lender_ids.
              required:
                - as_of
                - dated
                - dated_reason
                - n_parcels
                - n_with_open_lien
                - n_free_and_clear
                - n_avm
                - n_involuntary
                - n_lenders
              additionalProperties: false
            - type: 'null'
          description: The financing slice. Null when this market has none.
        permits:
          anyOf:
            - type: object
              properties:
                as_of:
                  anyOf:
                    - type: string
                      description: Calendar date, YYYY-MM-DD.
                    - type: 'null'
                  description: >-
                    The effective date of the loaded permit snapshot,
                    YYYY-MM-DD.
                n_permits:
                  anyOf:
                    - type: integer
                      minimum: -9007199254740991
                      maximum: 9007199254740991
                    - type: 'null'
                  description: Permits served for this market.
                n_parcels:
                  anyOf:
                    - type: integer
                      minimum: -9007199254740991
                      maximum: 9007199254740991
                    - type: 'null'
                  description: Parcels with at least one permit.
                n_unmatched:
                  anyOf:
                    - type: integer
                      minimum: -9007199254740991
                      maximum: 9007199254740991
                    - type: 'null'
                  description: >-
                    Permits in the county file that landed on no parcel of the
                    market, so the API does not serve them.
                jurisdictions:
                  anyOf:
                    - type: array
                      items:
                        type: object
                        properties:
                          jurisdiction:
                            type:
                              - string
                              - 'null'
                          n_permits:
                            anyOf:
                              - type: integer
                                minimum: -9007199254740991
                                maximum: 9007199254740991
                              - type: 'null'
                          last_issue_date:
                            anyOf:
                              - type: string
                                description: Calendar date, YYYY-MM-DD.
                              - type: 'null'
                          windows_measured:
                            description: >-
                              True when the jurisdiction issued a permit in the
                              12 months before as_of. False when it did not: its
                              feed is stale, so its parcels carry null 24-month
                              and 36-month windows. The rule applies in every
                              market. Read those null windows (n_permits_24m,
                              n_open_permits_12m, major_work_36m, tags_24m,
                              job_value_24m) as unmeasured, not as permit-free.
                              The negative permit filters of the search leave
                              such parcels out. Null only on a coverage row
                              built before the flag existed.
                            type:
                              - boolean
                              - 'null'
                        required:
                          - jurisdiction
                          - n_permits
                          - last_issue_date
                          - windows_measured
                        additionalProperties: false
                    - type: 'null'
                  description: >-
                    The issuing jurisdictions, largest first, each with its
                    permit count, its newest issue date and its windows_measured
                    flag.
              required:
                - as_of
                - n_permits
                - n_parcels
                - n_unmatched
                - jurisdictions
              additionalProperties: false
            - type: 'null'
          description: The permit snapshot. Null when this market has none.
        owner_profile:
          anyOf:
            - type: object
              properties:
                as_of:
                  anyOf:
                    - type: string
                      description: Calendar date, YYYY-MM-DD.
                    - type: 'null'
                  description: >-
                    The date of the delivery the Owner Profile block comes from,
                    YYYY-MM-DD.
                n_parcels:
                  anyOf:
                    - type: integer
                      minimum: -9007199254740991
                      maximum: 9007199254740991
                    - type: 'null'
                  description: Parcels carrying a profile.
                n_multi:
                  anyOf:
                    - type: integer
                      minimum: -9007199254740991
                      maximum: 9007199254740991
                    - type: 'null'
                  description: Parcels whose owner holds two or more properties.
                n_portfolio_5:
                  anyOf:
                    - type: integer
                      minimum: -9007199254740991
                      maximum: 9007199254740991
                    - type: 'null'
                  description: Parcels whose owner holds five or more.
              required:
                - as_of
                - n_parcels
                - n_multi
                - n_portfolio_5
              additionalProperties: false
            - type: 'null'
          description: The Owner Profile block. Null when this market has none.
        history:
          anyOf:
            - type: object
              properties:
                first_week:
                  anyOf:
                    - type: string
                      description: Calendar date, YYYY-MM-DD.
                    - type: 'null'
                  description: >-
                    The first weekly file the history lake replayed (the
                    baseline FULL).
                last_week:
                  anyOf:
                    - type: string
                      description: Calendar date, YYYY-MM-DD.
                    - type: 'null'
                  description: The last weekly file replayed.
                zips:
                  anyOf:
                    - type: array
                      items:
                        type: string
                    - type: 'null'
                  description: >-
                    The ZIP codes the history lake covers. A parcel outside them
                    has no history: `GET /v1/properties/{id}/history` answers
                    422 history_unavailable and the history block is null.
                n_parcels:
                  anyOf:
                    - type: integer
                      minimum: -9007199254740991
                      maximum: 9007199254740991
                    - type: 'null'
                  description: Parcels observed in the ZIP set.
                n_events:
                  anyOf:
                    - type: integer
                      minimum: -9007199254740991
                      maximum: 9007199254740991
                    - type: 'null'
                  description: Typed events on record.
                n_weeks:
                  anyOf:
                    - type: integer
                      minimum: -9007199254740991
                      maximum: 9007199254740991
                    - type: 'null'
                  description: Weekly files replayed.
                domains:
                  anyOf:
                    - type: object
                      propertyNames:
                        type: string
                      additionalProperties:
                        type: object
                        properties:
                          first_week:
                            anyOf:
                              - type: string
                                description: Calendar date, YYYY-MM-DD.
                              - type: 'null'
                          last_week:
                            anyOf:
                              - type: string
                                description: Calendar date, YYYY-MM-DD.
                              - type: 'null'
                          n_events:
                            anyOf:
                              - type: integer
                                minimum: -9007199254740991
                                maximum: 9007199254740991
                              - type: 'null'
                        required:
                          - first_week
                          - last_week
                          - n_events
                        additionalProperties: false
                    - type: 'null'
                  description: >-
                    Per domain, the weeks the lake covers it. Valuation and
                    financing end at the financing slice date, financing.as_of.
                    The rest run to last_week.
              required:
                - first_week
                - last_week
                - zips
                - n_parcels
                - n_events
                - n_weeks
                - domains
              additionalProperties: false
            - type: 'null'
          description: The history lake. Null when this market has none.
      required:
        - parcel_as_of
        - n_parcels
        - sale_mortgage_measured
        - financing
        - permits
        - owner_profile
        - history
      additionalProperties: false
      description: >-
        What the parcel products cover in one market. The parts are the parcel
        layer, the dated financing slice, the permit snapshot, the Owner Profile
        block and the history lake. Each carries its as-of date and counts.
    StrCoverageSource:
      type: object
      properties:
        source:
          type: string
          description: >-
            The source code of one city file, for example S1 (the Scottsdale
            licensed roll), P1 (the Phoenix active permits layer) or COH (the
            Houston registry).
        snapshot_date:
          anyOf:
            - type: string
              description: Calendar date, YYYY-MM-DD.
            - type: 'null'
          description: >-
            The date of the newest load of this source, YYYY-MM-DD. Null before
            the first load of this source.
        stale:
          type: boolean
          description: >-
            True when the newest load failed the freshness rule and the API
            still serves the previous snapshot. A load fails the rule when the
            count moved more than 30 percent, or when its newest date is more
            than 14 days old.
      required:
        - source
        - snapshot_date
        - stale
      additionalProperties: false
      description: >-
        One city file behind a jurisdiction's short-term rental data: the date
        of its newest load, and if that load is stale.
  headers:
    ETag:
      description: >-
        The entity tag of the answer, derived from the dataset version of the
        markets in the response and from the representation, not from the body.
        It moves only when a refresh rebuilds the tables of a market. On a JSON
        route, send it back as If-None-Match, and an unchanged dataset answers
        304 with no body. The API streams an export whatever the tag. GET
        /v1/dataset runs no query, so it is the lowest-cost place to send the
        tag. On every 2xx and the 304, never on an error.
      schema:
        type: string
    X-Request-Id:
      description: >-
        The id of this call. The edge mints it and also sends it as zp-rid, the
        gateway's own name for it. The API keys its log line for the call on it,
        and every error body repeats it as request_id. Log it on every response,
        not only on errors. A refusal the gateway answers itself carries zp-rid
        and request_id alone. Those refusals are a 401, a 403 quota_exceeded and
        a 429 at the limit of the plan.
      schema:
        type: string
    X-Rows:
      description: >-
        How many rows the body carries: data.length on a list, 1 on a single
        record. The size of the body, not a charge. Absent on a streamed export,
        whose count the API knows only when the stream ends, and on a 304.
      schema:
        type: integer
        minimum: 0
    X-Dataset-Version:
      description: >-
        The dataset version of every market in the response, as market=version
        pairs joined by commas (phx=1788469819 for one market). The header
        carries one pair per loaded market. The figures are the same as
        meta.coverage[].dataset_version, and you can read them without parsing
        the body. A version moves only when a refresh rebuilds the tables of the
        market, so fold the label into cache keys. On every 2xx and the 304,
        never on an error. Absent when the answer names no market: an empty
        deployment, or a GET /v1/coverage lookup outside every market.
      schema:
        type: string
    X-Data-End:
      description: >-
        The last deed date of every market in the response, as market=YYYY-MM-DD
        pairs joined by commas (phx=2026-08-12 for one market). The header
        carries one pair per loaded market. The dates are the same as
        meta.coverage[].data_end. On every 2xx and the 304, never on an error.
        Absent when the answer names no market: an empty deployment, or a GET
        /v1/coverage lookup outside every market.
      schema:
        type: string
    X-Row-Cap:
      description: >-
        The most rows an export streams, 50,000. The API counts the filtered set
        before the first row. It refuses a larger set as 422 csv_cap_exceeded,
        with cap and n_rows_at_least in the body. On every export answer and on
        that refusal.
      schema:
        type: integer
        minimum: 1
    Retry-After:
      description: >-
        Whole seconds to wait before you retry, never below 1. On a 429, the
        seconds until the spent bucket refills. On a 503, 1 for pool_saturated
        and 5 for ledger_unavailable, and none for database_unavailable. On a
        403 plan_limit for the name-search day cap, the seconds to the next UTC
        midnight, when the cap resets. The other plan limits carry none. The
        body repeats it as retry_after on the 429, the ledger refusal and the
        day cap.
      schema:
        type: integer
        minimum: 1
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        API key from the developer console (starts with zpka_). Create one at
        https://developers.investorlift.com/get-a-key.

````

## Related topics

- [List one lender's loans](/api-reference/endpoints/lenders-loans.md)
- [List one lender's borrowers](/api-reference/endpoints/lenders-borrowers.md)
- [One lender's loans per hex cell](/api-reference/endpoints/lenders-cells.md)
- [List the borrowers of one lender](/api-reference/lenders/list-the-borrowers-of-one-lender.md)
- [Count one lender's loans per hex cell for a map](/api-reference/lenders/count-one-lenders-loans-per-hex-cell-for-a-map.md)
