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

# Prospecting Contacts

> Search Lusha's contact database with rich ICP filters across contact and company attributes. Returns paginated, lightweight previews - enrich the returned IDs to reveal emails and phones.

Prospecting Contacts searches Lusha's contact database for people who match your Ideal Customer Profile. Filter on contact attributes (title, seniority, department, location, existing data points, signals) and on attributes of the contact's current company (size, revenue, industry, technologies, intent) in a single request.

The response is a page of lightweight contact **previews** - not full records. Each preview includes an `id`. Pass that `id` to [Enrich Contacts](/api-reference/enrich/enrich-contacts) to reveal emails, phone numbers, and the rest of the contact's data.

<Info>
  **Prospect, then enrich**

  | Step | Endpoint                                                          | Purpose                                                            |
  | ---- | ----------------------------------------------------------------- | ------------------------------------------------------------------ |
  | 1    | **POST /v3/contacts/prospecting**                                 | Find contacts matching your ICP filters; get back previews + `id`s |
  | 2    | [POST /v3/contacts/enrich](/api-reference/enrich/enrich-contacts) | Pass the `id`s from step 1 to reveal full contact data             |
</Info>

## Endpoint

```
POST https://api.lusha.com/v3/contacts/prospecting
```

**Authentication:** API key (`api_key` header)

Results are paginated up to 50,000 total (1,000 pages × 50 results per page).

***

## Request body

<ParamField body="pagination" type="object" required>
  Pagination controls.

  <Expandable title="pagination fields">
    <ParamField body="pagination.page" type="integer" default="0">
      Page number. Range: `0`–`1000`.
    </ParamField>

    <ParamField body="pagination.size" type="integer" default="25">
      Results per page. Range: `10`–`100`.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="filters" type="object" required>
  The top-level filter container. Provide at least one of `contacts` or `companies`.

  <Expandable title="filters.contacts">
    <ParamField body="filters.contacts.include" type="object">
      Criteria that matching contacts must satisfy.

      <Expandable title="include fields">
        <ParamField body="filters.contacts.include.names" type="string[]">
          Full names to match.
        </ParamField>

        <ParamField body="filters.contacts.include.jobTitles" type="string[]">
          Free-text job titles to match. Example: `["VP Sales", "Director of Sales"]`
        </ParamField>

        <ParamField body="filters.contacts.include.jobTitlesExactMatch" type="string[]">
          Job titles that must match exactly, rather than fuzzy-matching.
        </ParamField>

        <ParamField body="filters.contacts.include.normalizedJobTitles" type="string[]">
          Normalized/canonical job title values.
        </ParamField>

        <ParamField body="filters.contacts.include.searchText" type="string">
          Free-text search across contact fields. Max length: `200`.
        </ParamField>

        <ParamField body="filters.contacts.include.countries" type="string[]">
          Country codes. Example: `["US", "CA"]`
        </ParamField>

        <ParamField body="filters.contacts.include.locations" type="object[]">
          Geographic filters. Each object may include `city`, `state`, `country`, `continent`, and `countryGrouping`. Example: `[{ "country": "United States" }]`
        </ParamField>

        <ParamField body="filters.contacts.include.seniorityIds" type="integer[]">
          Seniority level IDs. Example: `[4, 5]`
        </ParamField>

        <ParamField body="filters.contacts.include.departments" type="string[]">
          Department names. Example: `["Sales", "Engineering"]`
        </ParamField>

        <ParamField body="filters.contacts.include.linkedinUrls" type="string[]">
          Match specific LinkedIn profile URLs.
        </ParamField>

        <ParamField body="filters.contacts.include.existingDataPoints" type="string[]">
          Only return contacts that already have specific data available. Example: `["work_email", "work_phone"]`
        </ParamField>

        <ParamField body="filters.contacts.include.signals" type="object">
          Filter contacts that have a signal of the specified types.

          <Expandable title="signals fields">
            <ParamField body="filters.contacts.include.signals.types" type="string[]">
              Signal types to match. Allowed values: `allSignals`, `promotion`, `companyChange`.
            </ParamField>

            <ParamField body="filters.contacts.include.signals.startDate" type="string">
              Earliest signal date, in `YYYY-MM-DD` format.
            </ParamField>
          </Expandable>
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField body="filters.contacts.exclude" type="object">
      Same fields as `include`. Contacts matching this criteria are removed from results.
    </ParamField>
  </Expandable>

  <Expandable title="filters.companies">
    <ParamField body="filters.companies.include" type="object">
      Criteria that the contact's current company must satisfy.

      <Expandable title="include fields">
        <ParamField body="filters.companies.include.names" type="string[]">
          Company names to include.
        </ParamField>

        <ParamField body="filters.companies.include.domains" type="string[]">
          Company domains to include. Example: `["lusha.com"]`
        </ParamField>

        <ParamField body="filters.companies.include.ids" type="string[]">
          Lusha company IDs to include.
        </ParamField>

        <ParamField body="filters.companies.include.locations" type="object[]">
          Geographic filters. Example: `[{ "country": "United States" }]`
        </ParamField>

        <ParamField body="filters.companies.include.sizes" type="object[]">
          Employee count ranges as `{ "min": ..., "max": ... }`. Example: `[{ "min": 50, "max": 500 }]`
        </ParamField>

        <ParamField body="filters.companies.include.revenues" type="object[]">
          Revenue ranges as `{ "min": ..., "max": ... }`.
        </ParamField>

        <ParamField body="filters.companies.include.technologies" type="string[]">
          Technologies the company uses. Example: `["Salesforce", "HubSpot"]`
        </ParamField>

        <ParamField body="filters.companies.include.technologiesCondition" type="string">
          `"or"` or `"and"` - how the `technologies` list is combined.
        </ParamField>

        <ParamField body="filters.companies.include.industriesLabels" type="string[]">
          Industry labels. Example: `["Software", "SaaS"]`
        </ParamField>

        <ParamField body="filters.companies.include.mainIndustriesIds" type="integer[]">
          Main industry IDs.
        </ParamField>

        <ParamField body="filters.companies.include.subIndustriesIds" type="integer[]">
          Sub-industry IDs.
        </ParamField>

        <ParamField body="filters.companies.include.intentTopics" type="string[]">
          Buyer intent topics. Example: `["Cloud Migration"]`
        </ParamField>

        <ParamField body="filters.companies.include.intentTopicsCondition" type="string">
          `"or"` or `"and"` - how the `intentTopics` list is combined.
        </ParamField>

        <ParamField body="filters.companies.include.topicCountThreshold" type="object[]">
          Ranges (`{ "min": ..., "max": ... }`) on the number of matched intent topics.
        </ParamField>

        <ParamField body="filters.companies.include.sicCodes" type="string[]">
          SIC industry classification codes.
        </ParamField>

        <ParamField body="filters.companies.include.naicsCodes" type="string[]">
          NAICS industry classification codes.
        </ParamField>

        <ParamField body="filters.companies.include.funding" type="object">
          Funding filters.

          <Expandable title="funding fields">
            <ParamField body="filters.companies.include.funding.isIpo" type="boolean">
              Filter for companies that have IPO'd.
            </ParamField>

            <ParamField body="filters.companies.include.funding.ranges" type="object[]">
              Funding amount ranges as `{ "min": ..., "max": ... }`.
            </ParamField>

            <ParamField body="filters.companies.include.funding.types" type="string[]">
              Funding round types. Example: `["Series B", "Series C"]`
            </ParamField>

            <ParamField body="filters.companies.include.funding.investors" type="string[]">
              Named investors.
            </ParamField>
          </Expandable>
        </ParamField>

        <ParamField body="filters.companies.include.foundedYear" type="object[]">
          Founding year ranges as `{ "min": ..., "max": ... }`.
        </ParamField>

        <ParamField body="filters.companies.include.businessModel" type="string[]">
          Allowed values: `B2B`, `B2C`, `B2G`.
        </ParamField>

        <ParamField body="filters.companies.include.companyType" type="string[]">
          Allowed values: `Government`, `Private Company`, `Public Company`, `Educational`, `Non Profit`, `Self Employed`.
        </ParamField>

        <ParamField body="filters.companies.include.linkedinUrls" type="string[]">
          Company LinkedIn URLs. Example: `["https://www.linkedin.com/company/microsoft"]`
        </ParamField>

        <ParamField body="filters.companies.include.keywords" type="string[]">
          Free-text keywords. Example: `["cloud", "artificial intelligence"]`
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField body="filters.companies.exclude" type="object">
      Same fields as `include`. Companies matching this criteria are removed from results.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="options" type="object">
  <Expandable title="options fields">
    <ParamField body="options.includePartialProfiles" type="boolean" default="true">
      When `true`, includes contacts with incomplete data in results.
    </ParamField>

    <ParamField body="options.excludeDnc" type="boolean">
      When `true`, excludes contacts whose phone numbers are all marked Do Not Call.
    </ParamField>
  </Expandable>
</ParamField>

Use the [Contact filter types](/api-reference/filters/contact-filter-types) and [Contact filter values](/api-reference/filters/contact-filter-values) endpoints to look up valid values (departments, seniority IDs, existing data points, and more) before building a request.

***

## Example request

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.lusha.com/v3/contacts/prospecting \
    --header 'api_key: YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
      "pagination": { "page": 0, "size": 50 },
      "filters": {
        "contacts": {
          "include": {
            "departments": ["Sales"],
            "locations": [{ "country": "United States" }],
            "existingDataPoints": ["work_email"]
          }
        },
        "companies": {
          "include": {
            "locations": [{ "country": "United States" }],
            "businessModel": ["B2B"],
            "companyType": ["Public Company"]
          }
        }
      },
      "options": {
        "includePartialProfiles": true,
        "excludeDnc": false
      }
    }'
  ```

  ```json Request body theme={null}
  {
    "pagination": { "page": 0, "size": 50 },
    "filters": {
      "contacts": {
        "include": {
          "departments": ["Sales"],
          "locations": [{ "country": "United States" }],
          "existingDataPoints": ["work_email"]
        }
      },
      "companies": {
        "include": {
          "locations": [{ "country": "United States" }],
          "businessModel": ["B2B"],
          "companyType": ["Public Company"]
        }
      }
    },
    "options": {
      "includePartialProfiles": true,
      "excludeDnc": false
    }
  }
  ```
</CodeGroup>

***

## Response

### 200 - Success

<ResponseField name="requestId" type="string">
  Unique ID for this search.
</ResponseField>

<ResponseField name="pagination" type="object">
  `page`, `size`, and `total` (total matching contacts across all pages).
</ResponseField>

<ResponseField name="results" type="object[]">
  Array of contact previews.

  <Expandable title="preview fields">
    <ResponseField name="results[].id" type="string">
      Lusha contact ID. Pass this to [Enrich Contacts](/api-reference/enrich/enrich-contacts) to reveal full data.
    </ResponseField>

    <ResponseField name="results[].clientReferenceId" type="string">
      Echoes back a client-supplied reference ID, if you passed one.
    </ResponseField>

    <ResponseField name="results[].firstName" type="string" />

    <ResponseField name="results[].lastName" type="string" />

    <ResponseField name="results[].jobTitle" type="object">
      `title`, `departments`, and `seniority`.
    </ResponseField>

    <ResponseField name="results[].company" type="object">
      `id`, `name`, and `domain` of the contact's current company.
    </ResponseField>

    <ResponseField name="results[].location" type="object">
      `country`, `state`, and `city`.
    </ResponseField>

    <ResponseField name="results[].socialLinks" type="object">
      `linkedin` profile URL.
    </ResponseField>

    <ResponseField name="results[].has" type="string[]">
      Fields already populated on this preview. Example: `["firstName", "lastName", "jobTitle", "location", "socialLinks", "emails"]`
    </ResponseField>

    <ResponseField name="results[].canReveal" type="object[]">
      Fields you can reveal via Enrich Contacts, each as `{ "field": "emails" | "phones", "credits": <integer> }`. `credits` is `0` when your account has already revealed that field for this contact.
    </ResponseField>

    <ResponseField name="results[].signalTypes" type="string[]">
      Signal types detected for this contact. Present when signal filtering was requested and matched.
    </ResponseField>

    <ResponseField name="results[].error" type="object">
      Present only when this item failed. `code` is one of `NOT_FOUND`, `COMPLIANCE_RESTRICTED`, `ENRICH_FAILED`; `message` explains why.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="billing" type="object">
  `creditsCharged` and `resultsReturned` for this request.
</ResponseField>

<Tip>
  **Billing:** Prospecting is charged per result via the `api_search` action. If you filter by `signals`, an additional charge applies per matched signal per result.
</Tip>

***

## Error codes

| Status | Meaning                                                 |
| ------ | ------------------------------------------------------- |
| `400`  | Bad request - invalid input data.                       |
| `401`  | Unauthorized - invalid or missing API key.              |
| `402`  | Payment required - insufficient credits.                |
| `403`  | Forbidden - account inactive, or V3 access not enabled. |
| `429`  | Too many requests - rate limit exceeded.                |

<ResponseExample>
  ```json 200 theme={null}
  {
    "requestId": "fa828378-7a8e-4e5d-9f72-0270e7f7ab51",
    "pagination": { "page": 0, "size": 50, "total": 670550 },
    "results": [
      {
        "id": "670138733",
        "firstName": "Ting",
        "lastName": "Tsou"
      }
    ],
    "billing": {
      "creditsCharged": 2,
      "resultsReturned": 50
    }
  }
  ```

  ```json 400 theme={null}
  {
    "statusCode": 400,
    "message": "Invalid request parameters"
  }
  ```

  ```json 402 theme={null}
  {
    "statusCode": 402,
    "message": "Insufficient credits for this operation"
  }
  ```

  ```json 403 theme={null}
  {
    "statusCode": 403,
    "message": "V3 API access is not enabled for your account"
  }
  ```
</ResponseExample>


## OpenAPI

````yaml post /v3/contacts/prospecting
openapi: 3.0.3
info:
  title: Lusha API Documentation
  version: 0.0.1
  x-logo:
    url: https://www.lusha.com/logo.png
  license:
    name: Proprietary
    url: https://lusha.com/legal/terms
  description: >
    <blockquote class="callout">

     **This is the Lusha API V3 documentation.** 
     
     V3 introduces a new search-then-enrich pattern, bulk operations, AI-powered lookalikes, and richer filter capabilities. All endpoints are under `https://api.lusha.com/v3/`.

      For more information on V3, refer to the [Migration Guide](/tutorials/v3-migration-guide).

    </blockquote>

      --- 

    Lusha provides a RESTful API for querying a comprehensive dataset of
    business profiles and company information. Built for teams running
    prospecting, enrichment, automation, and analytics workflows that need
    accurate, continuously updated business data. The API supports both
    real-time and bulk use cases.


    Use the Lusha API to **search for new prospects**, **enrich existing
    records**, **react to real-world changes**, and **expand coverage** with
    AI-powered lookalike recommendations.


    > All API requests must be made over **HTTPS**. All responses are returned
    in **JSON** format.


    --- 

    ## Available Endpoints


    | Category | Description |

    |---|---|

    | [**Search**](#tag/Search) | Find contacts or companies using known
    identifiers |

    | [**Enrich**](#tag/Enrich) | Retrieve full profile data for contacts or
    companies by ID |

    | [**Search & Enrich**](#tag/Search-and-Enrich) | Find and retrieve full
    contact or company data in a single call |

    | [**Prospecting**](#tag/Prospecting) | Filter-based search across contacts
    and companies |

    | [**Lookalikes**](#tag/Lookalikes) | AI-powered recommendations for similar
    contacts and companies |

    | [**Buying Group**](#tag/Buying-Group) | Identify decision makers,
    champions, and end users within target accounts |

    | [**Contacts Tables**](#tag/Contacts-Tables) | Persist, organize, and
    enrich contacts in reusable tables |

    | [**Companies Tables**](#tag/Companies-Tables) | Persist, organize, and
    enrich companies in reusable tables |

    | [**Signals**](#tag/Signals) | Real-world activity data for contacts and
    companies |

    | [**Website Visitors**](#tag/Website-Visits) | Companies ranked by
    website-visit signals for your tracked domains |

    | [**Conversations**](#tag/Conversations) | Search recorded sales
    conversations and fetch their transcripts |

    | [**Filters**](#tag/Filters) | Discover valid filter values for prospecting
    |

    | [**Webhooks**](#tag/Webhooks) | Real-time signal notifications via HTTP
    callbacks |

    | [**Account**](#tag/Account) | Usage, credits, rate limits, and pricing |


    <blockquote class="callout">

     **Waterfall Reveal for Contact Enrichment.**

      Enrich Contacts now supports `waterfallEnabled`. Fall through to your enabled third-party providers when Lusha's own data has no match, for extra reach on hard-to-match contacts. On by default once your account has it turned on - pass `waterfallEnabled: false` to opt a specific call out. [See Enrich Contacts](#operation/enrichContacts).

    </blockquote>


    ---


    ## Data Source and Privacy


    **Lusha is a search platform.** The data provided is not created or directly
    managed by Lusha. It is sourced from publicly available information and
    trusted business partners.


    For more details on how we collect and handle data, see our [Privacy
    Policy](https://lusha.com/legal/privacy-notice/).


    ---


    ## Legal Notices


    (a) Data brokers and other third-party platforms may not embed, expose, or
    otherwise provide access to the Lusha API, or to Data obtained through it,
    on or through their own website, product, or service, without Lusha's prior
    written consent.


    (b) Data obtained through the API may not be used to train or develop AI/ML
    systems, subject to the terms and exceptions outlined in the [Terms and
    Conditions](https://lusha.com/legal/terms).


    ---


    ## Authentication


    All API requests require an **API key** linked to your Lusha account and
    plan. Pass your key in the `api_key` request header on every call.


    > Generate and manage your API key in the [Lusha
    dashboard](https://dashboard.lusha.com/enrich/api).


    Store your API key securely and use it only in **server-side environments**.


    ---


    ## Rate Limiting


    Lusha enforces rate limits on a per-plan basis to ensure fair usage and
    platform stability. Limits are applied across multiple time windows (per
    minute, per hour, and per day), and vary depending on your account plan.


    Rate limits for the **Credit Usage API** differ from standard endpoint
    limits.


    > **Note:** To check your current plan's limits, visit the [Lusha Help
    Center](https://info.lusha.com/en/articles/163856-all-there-is-to-know-about-lusha-s-api)
    or contact your account manager.


    **Rate Limit Response Headers**


    | Header | Description |

    |--------|-------------|

    | `x-rate-limit-daily` | Total requests allowed per day |

    | `x-daily-requests-left` | Requests remaining in your daily quota |

    | `x-daily-usage` | Requests made in the current daily period |

    | `x-rate-limit-hourly` | Total requests allowed per hour |

    | `x-hourly-requests-left` | Requests remaining in your hourly quota |

    | `x-hourly-usage` | Requests made in the current hourly period |

    | `x-rate-limit-minute` | Total requests allowed per minute |

    | `x-minute-requests-left` | Requests remaining in the current minute window
    |

    | `x-minute-usage` | Requests made in the current minute window |


    ---

    ## Error Codes


    Lusha uses standard HTTP status codes to indicate the result of each
    request.


    | Code | Name | Description |

    |------|------|-------------|

    | `200` | OK | Request was successful |

    | `400` | Bad Request | Request is malformed or missing required fields |

    | `401` | Unauthorized | API key is missing or invalid |

    | `402` | Payment Required | Insufficient credits or payment needed |

    | `403` | Forbidden | Account is inactive. Contact support@lusha.com |

    | `404` | Not Found | Endpoint or resource does not exist |

    | `429` | Too Many Requests | Rate limit or daily quota exceeded |

    | `451` | Unavailable For Legal Reasons | Request blocked due to GDPR
    regulations |

    | `499` | Client Closed Request | Request timed out before completing |

    | `5XX` | Server Error | Issue on Lusha's end. Retry with exponential
    backoff |


    **Error Response Format**


    ```json

    {
      "statusCode": 400,
      "message": "Invalid request parameters"
    }

    ```


    **Tables-specific error codes**


    | Code | Status | Meaning |

    |---|---|---|

    | `TABLE_NOT_FOUND` | 404 | The `table_id` does not exist or is not
    accessible to this account |

    | `COLUMN_NOT_FOUND` | 404 | The `column_id` does not exist on the given
    table |

    | `TABLE_NAME_CONFLICT` | 409 | A table with this name already exists |


    Tables error bodies use the shape `{ "message": "...", "code": <status>, ...
    }` rather than the `statusCode`/`errors` shape used elsewhere in this doc.


    **Limits:** up to 500 entity IDs per add/remove call · max 50,000 entities
    per table · max 500 tables per account · `page` 0–100 · `size` default 100.


    **Tips for Handling Errors**


    - Verify your API key is correct and active

    - Read the `message` field for specific troubleshooting details

    - For `429` errors, wait before retrying

    - For `5XX` errors, use exponential backoff before retrying
  contact:
    name: Lusha Support
    url: https://api.lusha.com
    email: support@lusha.com
  termsOfService: https://lusha.com/legal/terms
  x-privacy-policy:
    name: Privacy Policy
    url: https://lusha.com/legal/privacy-notice/
servers:
  - url: https://api.lusha.com
    description: Production server
security:
  - ApiKeyAuth: []
tags:
  - name: Search
    description: >
      **Search APIs:** Find contacts or companies using known identifiers.


      Look up contacts by `id`, `linkedinUrl`, `email`, or `firstName` +
      `lastName` + `companyName`/`companyDomain`. Look up companies by `id`,
      `name`, or `domain`.


      Returns a non-PII preview of each profile with a `has` field listing
      available data points and a `canReveal` field showing what can be unlocked
      via Enrich.


      > **Billing:** Charged per successful result via the `api_search` action.
    x-tag-expanded: true
  - name: Enrich
    description: >
      **Enrich APIs:** Retrieve full profile data for contacts or companies by
      ID.


      Pass IDs from Search results to reveal emails, phones, and full
      firmographic data.


      > **Billing:** Charged per revealed field via per-datapoint pricing
      (`revealEmail`, `revealPhone`, `reveal_company`).
    x-tag-expanded: true
  - name: Search & Enrich
    description: >
      **Search & Enrich APIs:** Find and retrieve full contact or company data
      in a single call.


      Combines Search and Enrich into one request. Provide identifiers and
      control what gets revealed via the `reveal` field. Premium data points are
      never returned unless you request them explicitly in `reveal`.


      > **Billing:** Two charges apply - one for the search (`api_search`) and
      one per revealed field.
    x-tag-expanded: true
  - name: Prospecting
    description: >
      **Prospecting APIs:** Filter-based search for contacts and companies.


      Use prospecting to find new records that match your Ideal Customer Profile
      (ICP). Apply rich filters across:


      - **Contact attributes:** title, seniority, location, signals

      - **Company attributes:** size, revenue, industry, technologies, intent


      Pass `tableId` to also persist matching results into an existing table.
      See [Contacts Tables](#tag/Contacts-Tables) or [Companies
      Tables](#tag/Companies-Tables).


      > **Billing:** Uses the capture/charge model with `api_search` actions.
      Signal charges apply additionally.
    x-tag-expanded: true
  - name: Lookalikes
    description: >
      **Lookalike APIs:** Use AI-powered recommendations to discover contacts
      and companies similar to your best existing customers. The Contact
      Lookalikes and Company Lookalikes endpoints return paginated results you
      can pipe directly into Enrich for full data.


      Pass `tableId` to also persist matching results into an existing table.
      See [Contacts Tables](#tag/Contacts-Tables) or [Companies
      Tables](#tag/Companies-Tables).
    x-tag-expanded: true
  - name: Buying Group
    description: >
      **Buying Group API:** Identify and prioritize the buying committee within
      a set of target companies.


      Supply up to 25 companies by `domain` or Lusha company `id`. The model
      scores and labels each returned contact with a persona role -
      `decision_maker`, `potential_champion`, or `end_user` - so you can
      prioritize outreach across the buying committee instead of working one
      contact at a time.


      Results are lightweight previews grouped by company. Use [Enrich
      Contacts](#operation/enrichContacts) with the returned `id` to reveal
      emails and phones.


      > **Billing:** Charged per contact returned via the `buyingGroupContact`
      action.
    x-tag-expanded: true
  - name: Contacts Tables
    description: >
      **Contacts Tables API:** Create and manage persistent tables of contacts
      inside Lusha.


      Tables are spreadsheets with configurable columns - default Lusha fields,
      enrichment data, Signals, AI insights, premium data points, CRM fields,
      and custom fields. Populate a table directly through the endpoints below,
      or pass `tableId` on Prospecting, Enrich, Signals, or Lookalike calls to
      persist those results automatically.


      Every surface that touches table data - this API, MCP, and the Workspace
      UI - reads and writes the same underlying data. Changes made through one
      surface are reflected on the others.


      **Working with tables:**

      - **Tables** - create, list, get status, update
      (rename/archive/visibility), delete

      - **Entities** - add, remove, or read the rows in a table

      - **Columns** - browse the Lusha column catalog, add columns, list,
      remove, or run a column across a table's rows


      **Owner resolution:** `owner.email` resolves to a user on your account and
      determines table ownership. **Required on every call when authenticating
      with an API key** - omitting it returns `400`. Optional for OAuth/token
      callers, since the caller is already identified by the token. Sent in the
      body as `owner: { email }` on `POST`/`PATCH` calls (and on `DELETE
      .../entities`, which carries a body); sent as a `?email=` query parameter
      on other `GET`/`DELETE` calls, which have no body.


      **Billing:**

      - Adding contacts to a table is free.

      - Reading entities (`GET .../entities`) charges per row returned.

      - Create / List / Get / Update / Delete / Column Catalog / Add Columns /
      List Columns / Remove Column / Remove Entities are free. (Add Columns is
      free today - credits aren't charged for it yet.)

      - Running a column charges per row per the column's tier (contact
      enrichment per row with data; signal/AI/score per row per run).

      - Non-public-API-plan accounts always resolve to `0` credits charged.


      **Limits:** up to 500 entity IDs per add/remove call · max 50,000 entities
      per table · max 500 tables per account.


      See also: [Companies Tables](#tag/Companies-Tables).
    x-tag-expanded: true
  - name: Companies Tables
    description: >
      **Companies Tables API:** Create and manage persistent tables of companies
      inside Lusha.


      Tables are spreadsheets with configurable columns - default Lusha fields,
      enrichment data, Signals, AI insights, premium data points, CRM fields,
      and custom fields. Populate a table directly through the endpoints below,
      or pass `tableId` on Prospecting, Enrich, Signals, or Lookalike calls to
      persist those results automatically.


      Every surface that touches table data - this API, MCP, and the Workspace
      UI - reads and writes the same underlying data. Changes made through one
      surface are reflected on the others.


      **Working with tables:**

      - **Tables** - create, list, get status, update
      (rename/archive/visibility), delete

      - **Entities** - add, remove, or read the rows in a table

      - **Columns** - browse the Lusha column catalog, add columns, list,
      remove, or run a column across a table's rows


      **Owner resolution:** `owner.email` resolves to a user on your account and
      determines table ownership. **Required on every call when authenticating
      with an API key** - omitting it returns `400`. Optional for OAuth/token
      callers, since the caller is already identified by the token. Sent in the
      body as `owner: { email }` on `POST`/`PATCH` calls (and on `DELETE
      .../entities`, which carries a body); sent as a `?email=` query parameter
      on other `GET`/`DELETE` calls, which have no body.


      **Billing:**

      - Adding companies to a table charges `reveal_company` per **newly added**
      company, deduped so duplicates and already-present companies aren't
      charged again.

      - Reading entities (`GET .../entities`) charges per row returned.

      - Create / List / Get / Update / Delete / Column Catalog / Add Columns /
      List Columns / Remove Column / Remove Entities are free. (Add Columns is
      free today - credits aren't charged for it yet.)

      - Running a column charges per row per the column's tier (company
      enrichment once per company per table - re-runs on an already-paid company
      are free; signal/AI/score per row per run).

      - Non-public-API-plan accounts always resolve to `0` credits charged.


      **Limits:** up to 500 entity IDs per add/remove call · max 50,000 entities
      per table · max 500 tables per account.


      See also: [Contacts Tables](#tag/Contacts-Tables).
    x-tag-expanded: true
  - name: Signals
    description: >
      Real-world activity data for contacts and companies.


      Signals are available as standalone endpoints or as an optional `signals`
      filter on Search and Prospecting endpoints.



      **Contact signal types:** `promotion`, `companyChange`, `allSignals`


      ----


      **Company signal types:** `headcountIncrease1m/3m/6m/12m`,
      `headcountDecrease1m/3m/6m/12m`, `surgeInHiring`,
      `surgeInHiringByDepartment`, `surgeInHiringByLocation`,
      `websiteTrafficIncrease`, `websiteTrafficDecrease`, `itSpendIncrease`,
      `itSpendDecrease`, `riskNews`, `commercialActivityNews`,
      `corporateStrategyNews`, `financialEventsNews`, `peopleNews`,
      `marketIntelligenceNews`, `productActivityNews`, `allSignals`


      ----


      **Signal Score:** Use [Score Companies by Signal
      Activity](#operation/getCompanySignalScores) or [Score Contacts by Signal
      Activity](#operation/getContactSignalScores) to get a single aggregate
      momentum score ([0,1]) plus the active signal breakdown for a batch of
      entities, rather than a raw event list.


      ----


      Credits are charged per matched signal per result via `showSignalsContact`
      or `showSignalsCompany`.


      Pass `tableId` to also persist matching results into an existing table.
      See [Contacts Tables](#tag/Contacts-Tables) or [Companies
      Tables](#tag/Companies-Tables).
    x-tag-expanded: true
  - name: Website Visits
    description: >
      Retrieve companies ranked by website-visit signals for your tracked
      domains.

       Domains must be configured for tracking in the dashboard. Each result combines a V3 company firmographic preview with behavioral visit metrics (score, sessions, unique visitors, avg session length, and more).
    x-tag-expanded: true
  - name: Conversations
    description: >
      **Conversations API:** Search the sales conversations recorded by Lusha
      Conversations for your account, and fetch speaker-attributed transcripts.


      Search Conversations returns each conversation's metadata, AI summary,
      action items, risks, objections, competitor mentions, coaching analysis,
      and chapters - transcripts are not included. Fetch the transcript for a
      single conversation separately.


      **Two search modes on one contract:**

      - **Keyword mode** - supply `query` to rank conversations by transcript
      content. All other filters are ignored.

      - **Filter mode** - omit `query` and supply the structural filters (dates,
      contact names, company domains, meeting titles).


      Only conversations belonging to your account whose post-call processing
      has completed are returned. `summary`, `coaching`, and `chapters` come
      from an asynchronous pipeline and are `null`/empty until it has run - a
      `null` summary means "analysis not ready yet", not "nothing found".


      > **Billing:** Search charges 1 credit per block of up to 25 conversations
      returned (via `ci_meeting_data_export`); a request that returns nothing is
      free. Transcript charges 1 credit per successful request (via
      `ci_transcript_analysis`); a `404` is never charged. While the relevant
      action isn't yet seeded on your account's pricebook, the endpoint stays
      free (`billing.creditsCharged` is `0`).
    x-tag-expanded: true
  - name: Filters
    description: >
      **Filter APIs:** Retrieve available filter values for prospecting.


      Use the discovery endpoints to list all available filter types, then fetch
      valid values for a specific filter type before building a prospecting
      request.


      **Contact filter types:** `departments`, `seniority`,
      `existingDataPoints`, `countries`, `locations`


      **Company filter types:** `names`, `sizes`, `revenues`, `locations`,
      `sics`, `naics`, `industriesLabels`, `intentTopics`, `technologies`
    x-tag-expanded: true
  - name: Webhooks
    description: >
      Subscribe to real-time notifications when contacts change jobs or
      companies experience key business events.


      Webhooks deliver HTTP POST requests to your endpoints when signals occur -
      from promotions and job changes to company growth.


      > For a full list of available signals, refer to [**Signal
      Options**](https://docs.lusha.com/apis/openapi/signals/getsignaloptions).

      ---

      **Key Features:**

      - Real-time contact & company signal notifications

      - Bulk subscription management (up to 25 items per request)

      - Secure delivery with HMAC-SHA256 signatures

      - Delivery monitoring with audit logs

       **Available Endpoints:**

      | Method | Endpoint | Purpose |

      |--------|----------|---------|

      | POST | `/api/subscriptions` | Create subscriptions (bulk supported) |

      | GET | `/api/subscriptions` | List all subscriptions |

      | GET | `/api/subscriptions/{id}` | Get subscription by ID |

      | PATCH | `/api/subscriptions/{id}` | Update subscription |

      | POST | `/api/subscriptions/delete` | Delete subscriptions (bulk
      supported) |

      | POST | `/api/subscriptions/{id}/test` | Test subscription delivery |

      | GET | `/api/audit-logs` | Get webhook delivery logs |

      | GET | `/api/audit-logs/stats` | Get delivery statistics |

      | GET | `/api/account/secret` | Get account webhook secret |

      | POST | `/api/account/secret/regenerate` | Regenerate account secret |

      | POST | `/api/subscriptions/opt-out` | Subscribe to contact opt-out
      notifications |


      > **Webhook Delivery Acknowledgment:** When receiving webhook deliveries
      (POST requests), your endpoint must acknowledge with a specific response
      format. See the [Create Subscription](#operation/createSubscription)
      endpoint for the required acknowledgment structure.
            ---

      <details>

      <summary><strong>Rate Limits</strong></summary>


      | Operation | Limit |

      |-----------|-------|

      | API Requests | 100 requests/minute per account |

      | Create Subscriptions | 25 items per request |

      | Delete Subscriptions | 25 items per request |


      </details>


      ---


      <details>

      <summary><strong>Security & Verification</strong></summary>


      **HTTPS Requirement:**

      - Production webhook URLs **must** use HTTPS

      - HTTP URLs are not accepted


      **Signature Verification:**


      All webhook deliveries include an `X-Lusha-Signature` header containing an
      HMAC-SHA256 signature. Verify this signature to ensure the request is from
      Lusha:


      1. Extract the `X-Lusha-Signature` and `X-Lusha-Timestamp` headers

      2. Concatenate: `timestamp + "." + JSON.stringify(payload)`

      3. Compute HMAC-SHA256 using your webhook secret

      4. Compare the computed signature with the received signature


      **Example (Node.js):**

      ```javascript

      const crypto = require('crypto');


      function verifySignature(payload, signature, timestamp, secret) {
        const signedPayload = `${timestamp}.${JSON.stringify(payload)}`;
        const expectedSignature = crypto
          .createHmac('sha256', secret)
          .update(signedPayload)
          .digest('hex');
        
        return crypto.timingSafeEqual(
          Buffer.from(signature),
          Buffer.from(expectedSignature)
        );
      }

      ```


      > **Security Best Practice:** Always verify webhook signatures to prevent
      spoofed requests.


      </details>


      ---


      <details>

      <summary><strong>Credits & Billing</strong></summary>


      **Credit Charges:**

      - Credits are charged when signals are detected and delivered to your
      webhook

      - The `creditsCharged` field in the webhook payload indicates how many
      credits were used

      - Credits are deducted from your account balance per signal type


      **No Duplicate Charges:**

      - Each signal is delivered once and charged once

      - Webhook delivery retries do not incur additional charges


      </details>


      ---


      <details>

      <summary><strong>Error Response Format</strong></summary>


      All error responses follow this format:

      ```json

      {
        "statusCode": 400,
        "message": "Validation failed",
        "errors": ["entityType must be one of: contact, company"]
      }

      ```


      | Field | Type | Description |

      |-------|------|-------------|

      | `statusCode` | number | HTTP status code |

      | `message` | string | Error message |

      | `errors` | string[] | Detailed error messages (optional) |


      </details>
          
      ---
    x-tag-expanded: true
  - name: Account
    description: >
      **Account API:** Retrieve account usage, credit balance, rate limits, plan
      details, and pricing.


      Use this endpoint to monitor consumption and understand the credit cost of
      each action type in the public API flow.


      > **Rate limit:** 5 requests per minute.
    x-tag-expanded: true
paths:
  /v3/contacts/prospecting:
    post:
      tags:
        - Prospecting
      summary: Prospecting Contacts
      description: >
        Search for contacts that match your Ideal Customer Profile using rich
        filter criteria.


        **Filter by contact attributes:**

        - Job title, seniority, department

        - Location (city, state, country, continent)

        - Existing data points (e.g. only contacts with a known work email)

        - Signal activity (promotion, job change)


        **Filter by company attributes:**

        - Size, revenue, industry, technologies

        - Location, intent topics, funding


        Use `options.maxContactsPerCompany` (1–20) to cap how many contacts are
        returned per company; `pagination.size` still controls the page size. 


        Use the returned contact `id` values with Enrich Contacts to reveal
        emails and phones.


        > **Billing:** Charged per result via `api_search`. If signals are
        requested, an additional charge applies per matched signal per result.


        > **Persisting to a table:** Pass `tableId` to also persist matching
        results into an existing table. This is additive - the primary response
        is unchanged, and a `tableWrite` object is added showing what happened
        on the table side. See [Contacts Tables](#tag/Contacts-Tables).
      operationId: prospectingContacts
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/V3ProspectingContactsRequest'
            example:
              pagination:
                page: 0
                size: 100
              filters:
                contacts:
                  include:
                    departments:
                      - Sales
                    locations:
                      - country: United States
                    existingDataPoints:
                      - work_email
                companies:
                  include:
                    locations:
                      - country: United States
                    foundedYear:
                      - min: 2000
                    businessModel:
                      - B2B
                    companyType:
                      - Public Company
                    linkedinUrls:
                      - https://www.linkedin.com/company/google
                    keywords:
                      - fintech
                  exclude:
                    domains:
                      - competitor.com
                    companyType:
                      - Self Employed
              tableId: '482910'
              options:
                includePartialProfiles: true
                excludeDnc: false
                maxContactsPerCompany: 2
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/V3ProspectingContactsResponse'
              example:
                requestId: fa828378-7a8e-4e5d-9f72-0270e7f7ab51
                pagination:
                  page: 0
                  size: 50
                  total: 670550
                  totalGuaranteed: true
                  totalDescription: Exact contact count (up to 2 per company)
                results:
                  - id: '670138733'
                    firstName: Ting
                    lastName: Tsou
                tableWrite:
                  tableId: '482910'
                  added: 48
                  alreadyPresent: 2
                  columnsCreated: []
                  rowsProcessed: 50
                  rowsCharged: 48
                  rowsAlreadyPaidInTable: 2
                billing:
                  creditsCharged: 2
                  resultsReturned: 50
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
components:
  schemas:
    V3ProspectingContactsRequest:
      type: object
      required:
        - pagination
        - filters
      properties:
        pagination:
          $ref: '#/components/schemas/V3PaginationRequest'
        filters:
          $ref: '#/components/schemas/V3ProspectingContactFilters'
        tableId:
          type: string
          description: >-
            Optional. If provided, results are also persisted to this table. See
            the Tables API.
          example: '482910'
        options:
          type: object
          properties:
            includePartialProfiles:
              type: boolean
              default: true
            excludeDnc:
              type: boolean
            maxContactsPerCompany:
              type: integer
              minimum: 1
              maximum: 20
              description: >
                Caps how many contacts are returned per company - not the page
                size. `pagination.size` still controls the page size. Accepts
                1–20; omit for uncapped results.
              example: 2
    V3ProspectingContactsResponse:
      type: object
      properties:
        requestId:
          type: string
          format: uuid
        results:
          type: array
          items:
            $ref: '#/components/schemas/V3ContactPreview'
        pagination:
          $ref: '#/components/schemas/V3ProspectingContactsPagination'
        tableWrite:
          $ref: '#/components/schemas/TableWrite'
        billing:
          $ref: '#/components/schemas/V3Billing'
    V3PaginationRequest:
      type: object
      required:
        - page
        - size
      properties:
        page:
          type: integer
          minimum: 0
          maximum: 1000
          default: 0
          example: 0
        size:
          type: integer
          minimum: 10
          maximum: 100
          default: 25
          example: 25
    V3ProspectingContactFilters:
      type: object
      properties:
        contacts:
          type: object
          properties:
            include:
              $ref: '#/components/schemas/V3ContactFilterCriteria'
            exclude:
              $ref: '#/components/schemas/V3ContactFilterCriteria'
        companies:
          type: object
          properties:
            include:
              $ref: '#/components/schemas/V3CompanyFilterCriteria'
            exclude:
              $ref: '#/components/schemas/V3CompanyFilterCriteria'
    V3ContactPreview:
      type: object
      properties:
        clientReferenceId:
          type: string
          example: my-ref-1
        id:
          type: string
          example: '4389064704'
        firstName:
          type: string
          example: Orit
        lastName:
          type: string
          example: Shilvock
        jobTitle:
          type: object
          properties:
            title:
              type: string
              example: Vice President of Partnerships
            departments:
              type: array
              items:
                type: string
              example:
                - Business Development
            seniority:
              type: string
              example: Vice President
        company:
          type: object
          properties:
            id:
              type: string
              example: '16303253'
            name:
              type: string
              example: Lusha
            domain:
              type: string
              example: www.lusha.com
        location:
          type: object
          properties:
            country:
              type: string
              example: Israel
            state:
              type: string
              example: Tel Aviv District
            city:
              type: string
              example: Tel Aviv
        socialLinks:
          type: object
          properties:
            linkedin:
              type: string
              example: https://www.linkedin.com/in/orit-shilvock-6243bb5
        has:
          type: array
          items:
            type: string
          example:
            - firstName
            - lastName
            - jobTitle
            - location
            - socialLinks
            - emails
        canReveal:
          type: array
          items:
            $ref: '#/components/schemas/V3CanRevealItem'
        signalTypes:
          type: array
          items:
            type: string
          example:
            - promotion
            - companyChange
        error:
          $ref: '#/components/schemas/V3ItemError'
    V3ProspectingContactsPagination:
      type: object
      description: >
        Pagination for Prospecting Contacts. Extends the standard pagination
        object with two optional fields describing the `total` count. Both keys
        are omitted when not returned.
      allOf:
        - $ref: '#/components/schemas/V3PaginationResponse'
        - type: object
          properties:
            totalGuaranteed:
              type: boolean
              description: '`true` when `total` is an exact count rather than an estimate.'
              example: true
            totalDescription:
              type: string
              description: Human-readable explanation of `total`.
              example: Exact contact count (up to 2 per company).
    TableWrite:
      type: object
      description: >
        Added to a Prospecting, Enrich, Signals, or Lookalike response when
        `tableId` is passed on the request. The primary response is unaffected
        even if the table write fails.
      properties:
        tableId:
          type: string
          example: '482910'
        added:
          type: integer
          description: Number of new entities added to the table by this call.
          example: 3
        alreadyPresent:
          type: integer
          description: Number of entities from this call that were already in the table.
          example: 2
        columnsCreated:
          type: integer
          description: >-
            Number of columns auto-created by this call (e.g. a Signals column
            created on first use).
          example: 0
        rowsProcessed:
          type: integer
          description: Number of rows the column-run touched as part of this call.
          example: 5
        rowsCharged:
          type: integer
          description: Number of those rows that incurred a credit charge.
          example: 5
        rowsAlreadyPaidInTable:
          type: integer
          description: >-
            Number of those rows that were already paid for in this table and
            were not re-charged.
          example: 0
        creditsCharged:
          type: integer
          description: Credits charged specifically for this table write.
          example: 0
    V3Billing:
      type: object
      description: Credit usage summary for a V3 API request
      properties:
        creditsCharged:
          type: integer
          description: Total credits charged for this request
          example: 3
        resultsReturned:
          type: integer
          description: Number of successful results returned
          example: 1
    ErrorResponse:
      type: object
      required:
        - statusCode
        - message
      properties:
        statusCode:
          type: integer
          description: HTTP status code
          example: 400
        message:
          type: string
          description: Error message
          example: Validation failed
        errors:
          type: array
          items:
            type: string
          description: Detailed error messages (optional, only for validation errors)
          example:
            - 'entityType must be one of: contact, company'
    V3ContactFilterCriteria:
      type: object
      properties:
        names:
          type: array
          items:
            type: string
        jobTitles:
          type: array
          items:
            type: string
          example:
            - VP Sales
            - Director of Sales
        jobTitlesExactMatch:
          type: array
          items:
            type: string
        normalizedJobTitles:
          type: array
          items:
            type: string
        searchText:
          type: string
          maxLength: 200
        countries:
          type: array
          items:
            type: string
          example:
            - US
            - CA
        locations:
          type: array
          items:
            $ref: '#/components/schemas/V3Location'
        seniorityIds:
          type: array
          items:
            type: integer
          example:
            - 4
            - 5
        departments:
          type: array
          items:
            type: string
          example:
            - Sales
            - Engineering
        linkedinUrls:
          type: array
          items:
            type: string
        existingDataPoints:
          type: array
          items:
            type: string
          example:
            - work_email
            - work_phone
        signals:
          type: object
          properties:
            types:
              type: array
              items:
                type: string
                enum:
                  - allSignals
                  - promotion
                  - companyChange
            startDate:
              type: string
              format: date
        emails:
          type: array
          items:
            type: string
            format: email
          description: Personal data - no catalog.
        previousEmails:
          type: array
          items:
            type: string
            format: email
          description: Personal data - no catalog.
        previousJobTitle:
          type: array
          items:
            type: string
        skills:
          type: array
          items:
            type: string
          example:
            - Python
        certifications:
          type: array
          items:
            type: string
        awards:
          type: array
          items:
            type: string
        ids:
          type: array
          items:
            type: string
          description: Encrypted contact id from a prior search's `results[].id`.
        existingDataPointsCondition:
          type: string
          enum:
            - or
            - and
          description: Pairs with `existingDataPoints`.
        jobChangedAfterDate:
          type: string
          format: date
          description: >-
            Refinement-only - must be paired with a base filter (e.g.
            `jobTitles`).
        jobChangedLastViewDate:
          type: string
          format: date
          description: Refinement-only - must be paired with a base filter.
        education:
          type: object
          description: Refinement-only - must be paired with a base filter.
          properties:
            degrees:
              type: array
              items:
                type: string
            fieldsOfStudy:
              type: array
              items:
                type: string
            schools:
              type: array
              items:
                type: string
            startYearGte:
              type: integer
            graduationYearLte:
              type: integer
        score:
          type: object
          description: >
            Refinement-only - must be paired with a base filter. Raw 0–100
            contact score. Distinct from the `confidence` band ("A+"/"A")
            returned on enriched contacts, which is derived from this score
            (e.g. `A+` when score > 75).
          properties:
            minScore:
              type: integer
              minimum: 0
              maximum: 100
            maxScore:
              type: integer
              minimum: 0
              maximum: 100
        geographicDetails:
          type: array
          items:
            type: object
            properties:
              country:
                type: string
              zipcode:
                type: string
              distance:
                type: integer
                description: Radius in miles.
    V3CompanyFilterCriteria:
      type: object
      properties:
        names:
          type: array
          items:
            type: string
        domains:
          type: array
          items:
            type: string
          example:
            - lusha.com
        ids:
          type: array
          items:
            type: string
        locations:
          type: array
          items:
            $ref: '#/components/schemas/V3Location'
        sizes:
          type: array
          items:
            $ref: '#/components/schemas/V3Range'
          example:
            - min: 50
              max: 500
        revenues:
          type: array
          items:
            $ref: '#/components/schemas/V3Range'
        technologies:
          type: array
          items:
            type: string
          example:
            - Salesforce
            - HubSpot
        technologiesCondition:
          type: string
          enum:
            - or
            - and
          example: or
        industriesLabels:
          type: array
          items:
            type: string
          example:
            - Software
            - SaaS
        mainIndustriesIds:
          type: array
          items:
            type: integer
        subIndustriesIds:
          type: array
          items:
            type: integer
        intentTopics:
          type: array
          items:
            type: string
          example:
            - Cloud Migration
        intentTopicsCondition:
          type: string
          enum:
            - or
            - and
        intentMinScore:
          type: integer
          minimum: 1
          maximum: 100
        intentMaxScore:
          type: integer
          minimum: 1
          maximum: 100
        intentTopicsOperator:
          type: string
          enum:
            - or
            - and
            - any
            - all
          description: >
            Recommended over `intentTopicsCondition`. `any`/`all` are aliases
            for `or`/`and`. `intentTopicsCondition` is not deprecated and
            remains accepted.
        topicCountThreshold:
          type: array
          items:
            $ref: '#/components/schemas/V3Range'
        sicCodes:
          type: array
          items:
            type: string
        naicsCodes:
          type: array
          items:
            type: string
        funding:
          type: object
          description: >
            All funding sub-filters live under this single object. Every field
            is optional; combine any subset.
          properties:
            isIpo:
              type: boolean
            ranges:
              type: array
              items:
                type: object
                properties:
                  coverage:
                    type: string
                    enum:
                      - last_funding
                      - any_round
                      - total_funds
                      - last_round
                  min:
                    type: integer
                  max:
                    type: integer
            date:
              type: object
              properties:
                coverage:
                  type: string
                  enum:
                    - last_funding
                    - any_round
                    - total_funds
                    - last_round
                date:
                  type: string
                  format: date
            rounds:
              type: array
              items:
                type: object
                properties:
                  coverage:
                    type: string
                    enum:
                      - last_funding
                      - any_round
                      - total_funds
                      - last_round
                  round:
                    type: string
                    enum:
                      - pre_seed
                      - seed
                      - series_a
                      - series_b
                      - series_c
                      - series_d
                      - series_e
                      - series_f
                      - series_g
                      - series_h
                      - other
            names:
              type: array
              items:
                type: object
                properties:
                  coverage:
                    type: string
                    enum:
                      - last_funding
                      - any_round
                      - total_funds
                      - last_round
                  name:
                    type: string
                    enum:
                      - angel
                      - venture
                      - private_equity
                      - crowdfunding
                      - grant
                      - debt_financing
                      - other
            investors:
              type: array
              items:
                type: string
              description: Free text. Accepted but not currently applied downstream.
            types:
              type: array
              items:
                type: string
              description: Legacy free text. Accepted but not currently applied downstream.
        foundedYear:
          type: array
          description: >-
            Filter by year the company was founded. Supports `min` (greater than
            or equal) and `max` (less than or equal) range operators.
          items:
            type: object
            properties:
              min:
                type: integer
                example: 2000
              max:
                type: integer
                example: 2020
        businessModel:
          type: array
          description: 'Filter by business model. Accepted values: B2B, B2C, B2G.'
          items:
            type: string
            enum:
              - B2B
              - B2C
              - B2G
          example:
            - B2B
        companyType:
          type: array
          description: >-
            Filter by company type. Accepted values: Government, Private
            Company, Public Company, Educational, Non Profit, Self Employed.
          items:
            type: string
            enum:
              - Government
              - Private Company
              - Public Company
              - Educational
              - Non Profit
              - Self Employed
          example:
            - Public Company
        linkedinUrls:
          type: array
          description: Filter by company LinkedIn URLs.
          items:
            type: string
          example:
            - https://www.linkedin.com/company/google
        keywords:
          type: array
          description: Filter by keywords associated with the company.
          items:
            type: string
          example:
            - fintech
        specialities:
          type: array
          items:
            type: string
        exactSpecialities:
          type: array
          items:
            type: string
        exactKeywords:
          type: array
          items:
            type: string
        keywordsSearchFields:
          type: array
          items:
            type: string
        previousCompanyDomains:
          type: array
          items:
            type: string
        previousCompanyNames:
          type: array
          items:
            type: string
        geographicDetails:
          type: array
          items:
            type: object
            properties:
              country:
                type: string
              zipcode:
                type: string
              distance:
                type: integer
                description: Radius in miles.
        locationsZipcodes:
          type: array
          items:
            type: object
            properties:
              countryIso2:
                type: string
              zipcode:
                type: string
        headquarterZipcodes:
          type: array
          items:
            type: object
            properties:
              countryIso2:
                type: string
              zipcode:
                type: string
    V3CanRevealItem:
      type: object
      description: Indicates a data type that can be revealed and its credit cost
      properties:
        field:
          type: string
          enum:
            - emails
            - phones
          example: emails
        credits:
          type: integer
          description: Credit cost (0 when already revealed for this account)
          example: 1
    V3ItemError:
      type: object
      description: Per-item error in a batch response
      properties:
        code:
          type: string
          enum:
            - NOT_FOUND
            - COMPLIANCE_RESTRICTED
            - ENRICH_FAILED
            - NO_SCORE
          example: NOT_FOUND
        message:
          type: string
          example: Contact not found
    V3PaginationResponse:
      type: object
      properties:
        page:
          type: integer
          example: 0
        size:
          type: integer
          example: 25
        total:
          type: integer
    V3Location:
      type: object
      description: Location filter object used in prospecting requests
      properties:
        city:
          type: string
          example: San Francisco
        state:
          type: string
          example: California
        country:
          type: string
          example: United States
        continent:
          type: string
          example: North America
        countryGrouping:
          type: string
          example: EMEA
        region:
          type: string
          example: California
        countryIso2:
          type: string
          example: US
    V3Range:
      type: object
      description: Numeric range filter
      properties:
        min:
          type: integer
          minimum: 0
          example: 1
        max:
          type: integer
          example: 1000
  responses:
    BadRequest:
      description: Bad request - invalid input data
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            statusCode: 400
            message: Invalid request parameters
    Unauthorized:
      description: Unauthorized - invalid or missing API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            statusCode: 401
            message: Invalid API key
    PaymentRequired:
      description: Payment required - insufficient credits
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            statusCode: 402
            message: Insufficient credits for this operation
    Forbidden:
      description: >-
        Forbidden - account inactive, V3 access not enabled, or plan does not
        include this feature
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            accountInactive:
              summary: Account inactive
              value:
                statusCode: 403
                message: >-
                  Your account is not active. Please reach out to support at
                  support@lusha.com
            v3NotEnabled:
              summary: V3 access not enabled
              value:
                statusCode: 403
                message: V3 API access is not enabled for your account
    TooManyRequests:
      description: Too many requests - rate limit exceeded
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            statusCode: 429
            message: Too many requests. Please wait before making another request.
      headers:
        x-rate-limit-daily:
          description: Total requests allowed per day
          schema:
            type: integer
        x-daily-requests-left:
          description: Requests remaining in daily quota
          schema:
            type: integer
        x-rate-limit-hourly:
          description: Total requests allowed per hour
          schema:
            type: integer
        x-hourly-requests-left:
          description: Requests remaining in hourly quota
          schema:
            type: integer
        x-rate-limit-minute:
          description: Total requests allowed per minute
          schema:
            type: integer
        x-minute-requests-left:
          description: Requests remaining in current minute window
          schema:
            type: integer
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: api_key
      description: >
        Your Lusha API key. You can find this in your Lusha dashboard under API
        settings.

        Include this key in the `api_key` header for all requests.

````