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

# Filters

Describe the audience you want.

The named filter keys, listed in our column order rather than in include and exclude pairs. A list key is OR inside and AND across keys. An `exclude_*` key is the NOT of its twin. A range key comes as a `_min` / `_max` (inclusive) or `_after` / `_before` (exclusive) pair. A null column never matches a value key. Flat keys cover includes, ranges and the six common negations. Everything else goes through `where` with `not_in`.

## Named keys

| Key | Type | Description |
| --- | --- | --- |
| `countries` | array of Country | Contact countries to include. Send ISO-2 codes such as us, or English names such as Germany. |
| `exclude_countries` | array of Country | Contact countries to exclude. Send ISO-2 codes such as us, or English names such as Germany. |
| `has_linkedin` | boolean | True keeps only contacts that carry a LinkedIn URL. |
| `has_work_email` | boolean | True keeps only contacts that carry a work email. |
| `has_phone` | boolean | True matches contacts with a mobile or direct phone. False matches contacts without either. |
| `include_secondary_roles` | boolean | By default, filters match a person's main role. Set include_secondary_roles to true to also match their other current roles; the contact's top-level fields still show the main role. |
| `title_query` | string or array of string | Words in the current title. The match is case-insensitive and uses whole words: 'CTO' matches 'Co-founder & CTO' but not 'Director'. The words also match across punctuation: 'VP Sales' also matches 'VP, Sales' and 'VP-Sales'. Send an array to match any one of several phrases, for example ["VP Sales", "Vice President of Sales"]. A phrase that is blank after trimming answers 400 request.invalid. A leading or trailing wildcard answers 422 filter.rejected. For a substring match, use `where` with the `contains` operator on `title`. |
| `functions` | array of JobFunction | Job functions to include. |
| `exclude_functions` | array of JobFunction | Job functions to exclude. |
| `seniority` | array of Seniority | Seniority rungs to include. |
| `exclude_seniority` | array of Seniority | Seniority rungs to exclude. |
| `domains` | array of string | Current employer domains. A full URL reduces to a bare domain on input. |
| `exclude_domains` | array of string | Current employer domains to exclude. |
| `company_names` | array of string | Current employer names. Case-insensitive exact match after normalization. Lowercase, trim and collapse whitespace. Strip one trailing legal suffix with an optional comma, then a leading "the ". Legal suffixes: inc, inc., incorporated, llc, l.l.c., ltd, ltd., limited, corp, corp., corporation, co, co., gmbh, ag, sa, s.a., bv, b.v., plc, pty ltd, srl. An empty normalized name returns 400 request.invalid. Values are OR within this key and AND across keys. |
| `exclude_company_names` | array of string | The NOT of company_names after the same normalization. Lowercase, trim and collapse whitespace. Strip one trailing legal suffix with an optional comma, then a leading "the ". Legal suffixes: inc, inc., incorporated, llc, l.l.c., ltd, ltd., limited, corp, corp., corporation, co, co., gmbh, ag, sa, s.a., bv, b.v., plc, pty ltd, srl. An empty normalized name returns 400 request.invalid. Values are OR within this key and AND across keys. |
| `company_size` | array of CompanySize | Company employee bands to include. |
| `company_revenue` | array of CompanyRevenue | Company revenue ranges to include. Only companies with a known revenue range match; most small companies have none, so this key leaves them out. |
| `industries` | array of Industry | Company industries to include, as slugs such as software_development. A label such as 'Software Development' or 'IT Services & IT Consulting' is folded to its slug. Read the values from GET /contacts/schema/industries/values. |
| `exclude_industries` | array of Industry | Company industries to exclude, as slugs such as software_development. A label such as 'Software Development' or 'IT Services & IT Consulting' is folded to its slug. Read the values from GET /contacts/schema/industries/values. |
| `schools` | array of string | School names. It matches any school on the record. The match is exact on the stored value, so send the name as the record holds it. |
| `skills` | array of string | Skill names. It matches any skill on the record. The match is exact on the stored value, which is lowercase, and the input is lowercased. Read the values from GET /contacts/schema/skills/values. |
| `employee_count_min` | integer | The smallest company employee count, inclusive. |
| `employee_count_max` | integer | The largest company employee count, inclusive. |
| `founded_year_min` | integer | The earliest company founding year, inclusive. |
| `founded_year_max` | integer | The latest company founding year, inclusive. |
| `company_hq_countries` | array of Country | Company headquarters countries to include. Send ISO-2 codes such as us, or English names such as Germany. |
| `last_round_after` | YearMonth | The latest financing event is after this month, exclusive. |
| `last_round_before` | YearMonth | The latest financing event is before this month, exclusive. |
| `last_round_types` | array of FundingRoundType | Types of the latest financing event to include. |
| `total_funding_min` | integer | The smallest total funding in US dollars, inclusive. Missing funding is null and never matches. |
| `total_funding_max` | integer | The largest total funding in US dollars, inclusive. |
| `company_ids` | array of CompanyId | Company ids (`com_`) of the current employer to include. Take them from `POST /companies/search` or `POST /companies/lookup`. Values are OR within this key and AND across keys. Takes up to 1,000 ids. |

## Closed lists

- **Seniority** (frozen): `c_level`, `vp`, `director`, `manager`, `senior_ic`, `entry`, `founder_or_partner`, `unknown`. The seniority rung of the contact. The list is frozen. A C-level person whose title names a founder, owner or partner role is founder_or_partner; add it to reach founder CEOs.
- **JobFunction** (frozen): `operations`, `general_management`, `sales_and_bizdev`, `information_technology`, `education`, `healthcare_and_social_services`, `finance_and_accounting`, `manufacturing_and_production`, `engineering`, `customer_service`, `government_and_public_safety`, `marketing_and_advertising`, `human_resources`, `arts_and_creative`, `construction_and_trades`, `legal`, `supply_chain_and_logistics`, `procurement`, `writing_and_editorial`, `research_and_science`, `other`. The job function of the contact's main job. The list holds 21 values. `operations`: running the business day to day: operations, facilities, administration. `general_management`: business leadership, general management, strategy and consulting. `sales_and_bizdev`: selling, account management, partnerships and business development. `information_technology`: IT, systems, infrastructure, data and support for technology. `education`: teaching, instruction, academic and school roles. `healthcare_and_social_services`: clinical, nursing, care and social service roles. `finance_and_accounting`: finance, accounting, treasury and audit. `manufacturing_and_production`: making things: production, plant and manufacturing roles. `engineering`: software, hardware and other engineering roles. `customer_service`: customer service, support and customer success. `government_and_public_safety`: public administration, government, police, fire and military. `marketing_and_advertising`: marketing, advertising, brand and growth. `human_resources`: recruiting, people operations, compensation and training. `arts_and_creative`: design, art, culture and other creative work. `construction_and_trades`: construction, building and skilled trades. `legal`: lawyers, legal counsel, compliance and regulatory work. `supply_chain_and_logistics`: supply chain, logistics, transport and warehousing. `procurement`: purchasing and procurement. `writing_and_editorial`: writing, editing, journalism and publishing. `research_and_science`: research and development, laboratory and scientific roles. `other`: a function the source does not name.
- **EmailStatus** (frozen): `unknown`, `valid`, `invalid`, `catch_all`. The work email status comes from our data source; verified_at is the month the source last verified the address. The list is frozen.
- **CompanySize** (frozen): `1-10`, `11-50`, `51-200`, `201-500`, `501-1K`, `1K-5K`, `5K-10K`, `10K+`. The employee band of the company. The list is frozen.
- **FundingRoundType** (frozen): `pre_seed`, `seed`, `series_a`, `series_b`, `series_c_plus`, `private_equity`, `debt`, `other`. The eight funding categories. Series C and later rounds use `series_c_plus`.
- **Signal** (frozen): `one_year_at_company`, `new_in_role_90d`, `recent_job_change`, `founder`, `at_public_company`. The five contact signals. One year at the current company, a new role within 90 days, a recent employer change, a founder role, or employment at a public company. Filter on `signals` with `in` or `not_in` inside `where`.
- **Country** (frozen): an open list. A country as a lowercase ISO-2 slug, for example `us` or `de`. Aliases normalize on input: `US`, `USA` and `United States` all become `us`. Unknown values return 400 filter.unknown_value with allowed values and a hint to GET /contacts/schema/country/values.
- **Industry**: read the values from `/contacts/schema/industries/values`. A company industry slug. Read the allowed values from `GET /contacts/schema/industries/values`.

## The where tree

The condition tree. It is opened per account when the named keys cannot express the audience. The `signals` column is filtered here, with `in` or `not_in`.

One node of the condition tree: a group (`and`, `or`, `not`) or a leaf. The tree is at most 4 deep, holds at most 25 leaves, and takes at most 50 values in one `in`. An `and` or `or` group needs at least one child. A tree over 32 predicates, or a leaf with a leading wildcard, is rejected with 422 filter.rejected. A refused operator, value type or shape answers 422 filter.rejected and names what the column takes. Fields resolve against `GET /contacts/schema`, case-insensitively, and an unknown field returns 400 filter.unknown_key. A closed-list value in a where leaf folds its aliases, as a named key does, and an unknown value answers 400 filter.unknown_value.

Operators: `eq`, `neq`, `in`, `not_in`, `gt`, `gte`, `lt`, `lte`, `contains`, `exists`.

```json
{
  "where": {
    "and": [
      {
        "field": "country",
        "op": "in",
        "value": [
          "us",
          "ca"
        ]
      },
      {
        "or": [
          {
            "field": "title",
            "op": "contains",
            "value": "demand generation"
          },
          {
            "field": "seniority",
            "op": "eq",
            "value": "vp"
          }
        ]
      },
      {
        "not": {
          "field": "company_domain",
          "op": "eq",
          "value": "competitor.example"
        }
      }
    ]
  }
}
```

Skills carry no flat negation. Exclude them with `not_in` inside `where`.

```json
{
  "where": {
    "field": "skills",
    "op": "not_in",
    "value": [
      "cold calling"
    ]
  }
}
```

## Paging a search

Search answers with one page. Pass `page.next_cursor` back unchanged on the next call, and stop when it is null.

```javascript
const filter = { countries: ["us"], seniority: ["vp"] };
const rows = [];
let cursor = null;

do {
  const response = await fetch("https://api.leadmcp.ai/v1/contacts/search", {
    method: "POST",
    headers: { Authorization: "Bearer lm_live_YOUR_API_KEY", "Content-Type": "application/json" },
    body: JSON.stringify({ filter, limit: 50, cursor }),
  });
  const body = await response.json();
  rows.push(...body.data);
  cursor = body.page.next_cursor;
} while (cursor !== null);
```

To deliver a list, start an export instead of paging search.

## Aliases

- A full URL reduces to a bare domain on input.
- Aliases normalize on input: `US`, `USA` and `United States` all become `us`.
- An empty normalized name returns 400 request.invalid.
- Matching is exact: an email is lowercased and a LinkedIn URL reduces to its slug.
- The match is exact on the stored value, which is lowercase, and the input is lowercased.

## Stated limits

- A history key matches any entry on the record. The schools key matches any school. The skills key matches any skill.
- Past employers are not in the data: experience lists current roles only, main role first. Filter titles with title_query.
- A null column never matches a value key. Use has_work_email, has_phone and has_linkedin to ask for presence.
- Signals have no flat key. Filter them with `in` or `not_in` on `signals` inside `where`.
