---
title: "Lead feed (paid, priced per lead) — with a FREE preview"
method: GET
path: "/api/v1/leads/find"
tags: ["Leads"]
---

# Lead feed (paid, priced per lead) — with a FREE preview

`GET /api/v1/leads/find`

## Request

- Base URL: `https://propraven.com`
- URL: `https://propraven.com/api/v1/leads/find`
- Auth: one of:
  - HTTP bearer
  - none

The Machine Storefront's lead feed: the qualified target list for one SIGNAL in one STATE, delivered as lead records and priced PER LEAD.

Each lead carries its canonical_id (state:county:APN), owner, assessed value, that signal's own strength fields (years held, land/improvement ratio, flip profit, portfolio size, ...), a deterministic lead_score (1-100) and provenance {as_of, source}.

PRICE: per_lead = clamp($0.25 x S(signal strength) x V(asset-value tier), $0.05, $1.00); total = min(count x per_lead, $20). You pay for the leads DELIVERED -- min(matching rows, limit) -- and an empty result is never charged for. The exact total is advertised in the 402's accepts[0].maxAmountRequired (USDC atomic units, 6 decimals).

FREE PREVIEW: add preview=true for the exact count, the exact quote and up to three MASKED sample leads (APN truncated to state:county, house number stripped, owner name and every other people field withheld). No payment, no API key required; anonymous callers are IP-throttled at the free tier. The anonymous security alternative (`{}`) applies to the preview ONLY.

ACCOUNT OR PAYMENT FOR DELIVERY: a lead is an owner's name and mailing address by area -- people data. It is delivered to a PropRaven ACCOUNT (API key `Authorization: Bearer pz_...`, MCP OAuth token or signed-in session) and to a PAID pull without one: the leads are returned only once the x402 payment SETTLES or the `X-CREDIT-TOKEN` debit succeeds. An unpaid (non-preview) pull without an account is refused with HTTP 401 `code: "account_required"`, `reason: "people_data_requires_account"`.

PAID ACCESS (preview omitted) requires ONE of: (a) x402 pay-per-call -- send a base64 signed x402 PaymentPayload in the `X-PAYMENT` header (account credentials optional); on a successful build the leads are returned and the on-chain settlement receipt is in the `X-PAYMENT-RESPONSE` response header. (b) A prepaid `X-CREDIT-TOKEN` balance. (c) A genuine PAID PropRaven subscription entitlement (lead feeds are included). Being merely authenticated is NOT sufficient. (d) Anything else -> HTTP 402 whose `accepts` array carries the exact payment requirements for this pull.

OWNER CONTACT: each delivered lead carries `owner_contact` -- the owner's best mailing address, read from ONE address column family of the record with its ZIP, flagged mail_ready. `mail_ready=true` narrows the pull to parcels whose record carries a complete one-family mailing address (parcel-grain signals only). Each delivery is recorded in PropRaven's people-data access log before it is returned; if the log is unavailable the delivery is refused (503) and nothing is charged.

BOUNDED READS: every read carries a statement timeout (10 s with `mail_ready`, 25 s otherwise). A pull too broad to finish returns 503 `code: "lead_read_timeout"` telling you to narrow it (add `county`); nothing is charged.

NOTE on `distressed`: an assessment-derived cohort (a structure on the books assessed at a nominal value, on land that carries real value). It is NOT a pre-foreclosure, tax-lien or lis-pendens feed.

## Query parameters

- `signal` 'absentee' | 'long_hold' | 'entity_owned' | 'portfolio_owner' | 'high_land_ratio' | 'flip' | 'distressed', required
- `state` string, required
- `county` string
- `zip` string
- `value_min` integer
- `value_max` integer
- `limit` integer
- `preview` boolean
- `mail_ready` boolean
- `tax_delinquent` boolean

## Headers

- `X-PAYMENT` string

## Response `200`

Either the FREE masked preview (preview=true), the delivered lead set (paid), or an honest empty result (count 0 -- never charged for).

- union
  - LeadFeedPreview: The FREE preview (preview=true). `count` and `quote` are exactly what a paid call would deliver and charge.
    - `signal` string, required
    - `geo` object, required: The resolved request geography and filters.
      - `state` string, required
      - `state_fips` string, required
      - `county_fips` string, nullable, required
      - `zip` string, nullable, required
      - `value_min` integer, nullable, required
      - `value_max` integer, nullable, required
      - `mail_ready` boolean, required
      - `limit` integer, required
      - `tax_delinquent` boolean
    - `count` integer, required: Leads that will be / were delivered: min(matching rows, limit). This is the priced quantity.
    - `count_capped_at_limit` boolean, required: True when the count stopped at `limit` -- more leads exist beyond this pull.
    - `quote` LeadsQuote, required: The per-lead price quote. IDENTICAL in the free preview and in the 402/charge -- the previewed price is the paid price.
      - `per_lead` Money, required: A money amount as a decimal string plus its currency code.
        - `amount` string, required
        - `currency` string, required
      - `per_lead_usd` number, required: Unit price to 4dp: clamp($0.25 x S x V, $0.05, $1.00).
      - `total` Money, required: A money amount as a decimal string plus its currency code.
        - `amount` string, required
        - `currency` string, required
      - `total_usd` number, required: The amount actually charged: min(count x per_lead, $20).
      - `total_atomic_usdc` string, required: total_usd in USDC atomic units (6dp) -- what the 402 advertises as maxAmountRequired.
      - `asset` string, required
      - `count` integer, required: Leads priced = leads delivered.
      - `signal` string, required
      - `tier` 'low' | 'mid' | 'high' | 'premium', required: Asset-value tier, from the median assessed value of the delivered set.
      - `tier_label` string, required
      - `breakdown` object, required: The dials, so the price is auditable.
        - `base_per_lead` number, required
        - `S` number, required: Signal-strength multiplier (absentee 1.0 ... distressed 1.9).
        - `V` number, required: Asset-value tier multiplier (low 0.7, mid 1.0, high 1.5, premium 2.2).
        - `per_lead_raw` number, required: Per-lead price BEFORE the [$0.05, $1.00] clamp.
        - `total_raw` number, required: count x per_lead BEFORE the $20 per-call cap.
        - `capped` boolean, required: True when the $20 cap bound -- volume beyond it was free.
      - `pay` string[], required
      - `note` string, required
    - `preview` true, required
    - `sample` Lead[], required: Up to three MASKED leads: APN truncated to state:county, house number stripped, owner name withheld. Enough to judge the set, not enough to work it.
      - `canonical_id` string, required: state_fips:county_fips3:parcel_id (the assessor APN, never a PropRaven UUID). Null on the owner-grain portfolio_owner cohort. MASKED to "37:183:..." in the free preview.
      - `address` string, nullable, required: Situs address. House number stripped in the free preview.
      - `city` string, nullable, required
      - `state` string, nullable, required
      - `zip` string, nullable, required
      - `assessed_value` number, nullable, required: Total assessed value (sell price on the flip cohort).
      - `lead_score` number, nullable, required: Deterministic 1-100: the signal's base intent plus a bounded bonus from that signal's own strength column. Re-derivable, never random.
      - `owner_address` string, nullable, required
      - `owner_city` string, nullable, required
      - `owner_state` string, nullable, required
      - `is_out_of_state` boolean, nullable, required
      - `last_sale_date` string, nullable, required
      - `last_sale_price` number, nullable, required
      - `owner_name` string, nullable, required: Withheld (null) in the free preview. Delivered leads go to accounts only.
      - `masked` boolean, nullable, required: Present and true ONLY on free-preview sample leads.
      - `provenance` object, required
        - `source` string, nullable, required
        - `source_datasets` string[], required
        - `as_of` string, nullable, required: The serving epoch's generated_at.
        - `as_of_basis` string, nullable, required
        - `serving_epoch` string, nullable, required
        - `freshness_status` string, nullable, required
        - `catalog_reference` object, required
          - `catalog_version` string, nullable, required
          - `catalog_generated_at` string, nullable, required
          - `catalog_seal` object, required
            - `algorithm` string, nullable, required
            - `value` string, nullable, required
            - `covers` string, nullable, required
        - `note` string, nullable, required
      - `owner_contact` LeadOwnerContact: The owner's best mailing address on a delivered lead (account holders only). Lead pulls do not run the per-parcel permit phone lookup (`phone_status` is always not_checked); call GET /api/v1/owners/card for the full card.
        - `status` 'resolved' | 'not_found' | 'unavailable': unavailable = the contact read failed for this delivery (never a silently missing block).
        - `mailing` MailingAddress: One mailing address, read from ONE address column family of the record (owner_mailing_* or owner_*), never a street from one family and a ZIP from the other.
          - `basis` string, required: Where the address came from, e.g. owner_mailing, owner_address, deed_grantee.
          - `line1` string, required
          - `city` string, required
          - `state` string, required
          - `zip5` string, required
          - `zip4` string, nullable, required
          - `mail_ready` boolean, required: Street, city, state and a 5-digit ZIP are all present and consistent.
          - `po_box` boolean, required
          - `equals_situs` boolean, required: The mailing address is the property itself (owner-occupied).
          - `zip_conflict` boolean, required
          - `parcels_citing` number, required: Owner (name) cards only: how many of the owner's parcels carry this address.
          - `parcels_citing_basis` string, required
          - `label` string, required: The address as one mailing label.
          - `source` ContactSource, required
            - `authority` string, required: Who published the value, e.g. the county assessor.
            - `dataset` string, required
            - `url` string, nullable, required
          - `as_of` string, required
          - `as_of_basis` string, required
          - `grade` 'A' | 'B' | 'C' | 'D', required: A = the authority's own complete record; D = contradictory (hidden unless include_low_confidence=true).
        - `mail_ready` boolean
        - `phone_status` 'not_checked'
        - `hidden_low_confidence` integer
    - `note` string, required
    - `coverage_note` string: Present only when a known data gap explains an empty result (e.g. the owner-portfolio rollup's unpopulated state columns). Nothing is charged in that case.
    - `tax_delinquency_filter` TaxDelinquencyFilter: Present when `tax_delinquent=true` was applied.
      - `applied` boolean, required
      - `statuses` string[], required
      - `note` string, required
  - LeadFeed: The delivered lead set (paid), or an honest empty result when nothing matched (count 0, quote total $0, no payment taken).
    - `signal` string
    - `geo` object: The resolved request geography and filters.
      - `state` string
      - `state_fips` string, nullable
      - `county_fips` string, nullable
      - `zip` string, nullable
      - `value_min` integer, nullable
      - `value_max` integer, nullable
      - `limit` integer
      - `mail_ready` boolean
      - `tax_delinquent` boolean
    - `count` integer: Leads that will be / were delivered: min(matching rows, limit). This is the priced quantity.
    - `count_capped_at_limit` boolean: True when the count stopped at `limit` -- more leads exist beyond this pull.
    - `quote` LeadsQuote: The per-lead price quote. IDENTICAL in the free preview and in the 402/charge -- the previewed price is the paid price.
      - `per_lead` Money, required: A money amount as a decimal string plus its currency code.
        - `amount` string, required
        - `currency` string, required
      - `per_lead_usd` number, required: Unit price to 4dp: clamp($0.25 x S x V, $0.05, $1.00).
      - `total` Money, required: A money amount as a decimal string plus its currency code.
        - `amount` string, required
        - `currency` string, required
      - `total_usd` number, required: The amount actually charged: min(count x per_lead, $20).
      - `total_atomic_usdc` string, required: total_usd in USDC atomic units (6dp) -- what the 402 advertises as maxAmountRequired.
      - `asset` string, required
      - `count` integer, required: Leads priced = leads delivered.
      - `signal` string, required
      - `tier` 'low' | 'mid' | 'high' | 'premium', required: Asset-value tier, from the median assessed value of the delivered set.
      - `tier_label` string, required
      - `breakdown` object, required: The dials, so the price is auditable.
        - `base_per_lead` number, required
        - `S` number, required: Signal-strength multiplier (absentee 1.0 ... distressed 1.9).
        - `V` number, required: Asset-value tier multiplier (low 0.7, mid 1.0, high 1.5, premium 2.2).
        - `per_lead_raw` number, required: Per-lead price BEFORE the [$0.05, $1.00] clamp.
        - `total_raw` number, required: count x per_lead BEFORE the $20 per-call cap.
        - `capped` boolean, required: True when the $20 cap bound -- volume beyond it was free.
      - `pay` string[], required
      - `note` string, required
    - `coverage_note` string: Present only when a known data gap explains an empty result (e.g. the owner-portfolio rollup's unpopulated state columns). Nothing is charged in that case.
    - `note` string
    - `paid_via` 'x402' | 'credits' | 'subscription': Absent on an unpaid empty result (count 0).
    - `leads` Lead[]: The delivered, UNMASKED leads.
      - `canonical_id` string, required: state_fips:county_fips3:parcel_id (the assessor APN, never a PropRaven UUID). Null on the owner-grain portfolio_owner cohort. MASKED to "37:183:..." in the free preview.
      - `address` string, nullable, required: Situs address. House number stripped in the free preview.
      - `city` string, nullable, required
      - `state` string, nullable, required
      - `zip` string, nullable, required
      - `assessed_value` number, nullable, required: Total assessed value (sell price on the flip cohort).
      - `lead_score` number, nullable, required: Deterministic 1-100: the signal's base intent plus a bounded bonus from that signal's own strength column. Re-derivable, never random.
      - `owner_address` string, nullable, required
      - `owner_city` string, nullable, required
      - `owner_state` string, nullable, required
      - `is_out_of_state` boolean, nullable, required
      - `last_sale_date` string, nullable, required
      - `last_sale_price` number, nullable, required
      - `owner_name` string, nullable, required: Withheld (null) in the free preview. Delivered leads go to accounts only.
      - `masked` boolean, nullable, required: Present and true ONLY on free-preview sample leads.
      - `provenance` object, required
        - `source` string, nullable, required
        - `source_datasets` string[], required
        - `as_of` string, nullable, required: The serving epoch's generated_at.
        - `as_of_basis` string, nullable, required
        - `serving_epoch` string, nullable, required
        - `freshness_status` string, nullable, required
        - `catalog_reference` object, required
          - `catalog_version` string, nullable, required
          - `catalog_generated_at` string, nullable, required
          - `catalog_seal` object, required
            - `algorithm` string, nullable, required
            - `value` string, nullable, required
            - `covers` string, nullable, required
        - `note` string, nullable, required
      - `owner_contact` LeadOwnerContact: The owner's best mailing address on a delivered lead (account holders only). Lead pulls do not run the per-parcel permit phone lookup (`phone_status` is always not_checked); call GET /api/v1/owners/card for the full card.
        - `status` 'resolved' | 'not_found' | 'unavailable': unavailable = the contact read failed for this delivery (never a silently missing block).
        - `mailing` MailingAddress: One mailing address, read from ONE address column family of the record (owner_mailing_* or owner_*), never a street from one family and a ZIP from the other.
          - `basis` string, required: Where the address came from, e.g. owner_mailing, owner_address, deed_grantee.
          - `line1` string, required
          - `city` string, required
          - `state` string, required
          - `zip5` string, required
          - `zip4` string, nullable, required
          - `mail_ready` boolean, required: Street, city, state and a 5-digit ZIP are all present and consistent.
          - `po_box` boolean, required
          - `equals_situs` boolean, required: The mailing address is the property itself (owner-occupied).
          - `zip_conflict` boolean, required
          - `parcels_citing` number, required: Owner (name) cards only: how many of the owner's parcels carry this address.
          - `parcels_citing_basis` string, required
          - `label` string, required: The address as one mailing label.
          - `source` ContactSource, required
            - `authority` string, required: Who published the value, e.g. the county assessor.
            - `dataset` string, required
            - `url` string, nullable, required
          - `as_of` string, required
          - `as_of_basis` string, required
          - `grade` 'A' | 'B' | 'C' | 'D', required: A = the authority's own complete record; D = contradictory (hidden unless include_low_confidence=true).
        - `mail_ready` boolean
        - `phone_status` 'not_checked'
        - `hidden_low_confidence` integer
    - `tax_delinquency_filter` TaxDelinquencyFilter: Present when `tax_delinquent=true` was applied.
      - `applied` boolean, required
      - `statuses` string[], required
      - `note` string, required

## Other responses

- `400`: Invalid request: unknown signal, missing state, a zip filter on a cohort with no ZIP column, or an inverted value range, or `mail_ready` on the owner-grain portfolio_owner signal.
- `401`: No account and no payment on a paid (non-preview) pull -- leads are people data (`code: "account_required"`, `reason: "people_data_requires_account"`) -- or an invalid API key.
- `402`: Payment required. accepts[0].maxAmountRequired carries this pull's exact total (count x per-lead, capped at $20) in USDC atomic units. Pay per call via x402, hold a paid PropRaven subscription, or re-call with preview=true for the free masked preview.
- `405`: The endpoint exists but does not support this method. `Allow` lists the methods it does.
- `429`: Rate limit exceeded.
- `500`: Unexpected server error. The body never carries database or driver text.
- `503`: The pull was too broad to finish within its time bound (problem+json, `code: "lead_read_timeout"` -- narrow with `county`), or the people-data access log was unavailable (JSON `error`). Nothing is charged: a credit draw is refunded and an x402 claim released. With `tax_delinquent=true` before the tax delinquency layer's first load: problem+json `code: "tax_delinquency_unavailable"` (nothing charged).

---

[API](https://skmtc.dev/propraven/apis/propraven-api.md) · [All operations](https://skmtc.dev/propraven/apis/propraven-api/llms.txt) · [OpenAPI document](https://skmtc.dev/propraven/apis/propraven-api/revisions/37f8158c4eda?raw)
