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

# Worked examples

Buyer briefs, and the calls an agent makes for each one.

Each brief below is one sentence a buyer says. Under it are the calls an agent makes, in order, with the body it sends and the shape that comes back.

## A country, a seniority and a function

Brief: We sell to consulting leaders in the United States: size the audience, then show me a few of them.

`count_matches` (`POST /contacts/count`)

```json
{
  "filter": {
    "countries": [
      "us"
    ],
    "seniority": [
      "c_level",
      "vp"
    ],
    "functions": [
      "general_management"
    ],
    "has_work_email": true
  }
}
```

An envelope whose `data.count` is a whole number, or null with a `count_unavailable` warning. The call is free.

`find_contacts` (`POST /contacts/search`)

```json
{
  "filter": {
    "countries": [
      "us"
    ],
    "seniority": [
      "c_level",
      "vp"
    ],
    "functions": [
      "general_management"
    ],
    "has_work_email": true
  },
  "columns": [
    "id",
    "name",
    "title",
    "company_domain",
    "country",
    "seniority"
  ],
  "limit": 10
}
```

Up to ten rows in `data`, a `page` block with `returned`, `total` and `next_cursor`, and a `quota` block that is ten contact credits lighter.

## A list of target accounts

Brief: Show me everyone we can reach by email at our three named target accounts.

`count_matches` (`POST /contacts/count`)

```json
{
  "filter": {
    "domains": [
      "acme.example.com",
      "northwind.example.net",
      "globex.example.org"
    ],
    "has_work_email": true
  }
}
```

One number over all three domains, because a list key is OR inside one key.

`find_contacts` (`POST /contacts/search`)

```json
{
  "filter": {
    "domains": [
      "acme.example.com",
      "northwind.example.net",
      "globex.example.org"
    ],
    "has_work_email": true
  },
  "columns": [
    "id",
    "name",
    "title",
    "company",
    "company_domain",
    "work_email"
  ],
  "limit": 25
}
```

Rows from any of the three domains, mixed. On zero rows a `no_rows` warning names the keys that were applied.

## Decision makers at one company

Brief: Find the people who decide at one named account, with a work email.

`count_matches` (`POST /contacts/count`)

```json
{
  "filter": {
    "domains": [
      "acme.example.com"
    ],
    "seniority": [
      "c_level",
      "vp",
      "director"
    ],
    "has_work_email": true
  }
}
```

The number of leaders at the one domain, free. Add `functions` to keep only the buyer's department.

`find_contacts` (`POST /contacts/search`)

```json
{
  "filter": {
    "domains": [
      "acme.example.com"
    ],
    "seniority": [
      "c_level",
      "vp",
      "director"
    ],
    "has_work_email": true
  },
  "columns": [
    "id",
    "name",
    "title",
    "company_domain",
    "seniority",
    "work_email"
  ],
  "limit": 10
}
```

The leaders at that domain, one call for the whole account. On zero rows a `no_rows` warning names the keys that were applied.

## Decision makers across many accounts

Brief: Give me up to three leaders at each of our target accounts, in one list.

`count_matches` (`POST /contacts/count`)

```json
{
  "filter": {
    "domains": [
      "acme.example.com",
      "northwind.example.net",
      "globex.example.org",
      "initech.example.com"
    ],
    "seniority": [
      "c_level",
      "vp",
      "director"
    ],
    "has_work_email": true
  }
}
```

One number over every domain, free. The whole list goes in one call, never one call for each domain. One call takes up to 1,000 domains.

`find_contacts` (`POST /contacts/search`)

```json
{
  "filter": {
    "domains": [
      "acme.example.com",
      "northwind.example.net",
      "globex.example.org",
      "initech.example.com"
    ],
    "seniority": [
      "c_level",
      "vp",
      "director"
    ],
    "has_work_email": true
  },
  "columns": [
    "id",
    "name",
    "title",
    "company",
    "company_domain",
    "seniority"
  ],
  "max_rows_per_company": 3,
  "limit": 25
}
```

A page with at most three rows for each `company_domain`, so no single account fills the list. `start_export` takes the same filter and cap to deliver a file.

## The colleagues of a contact

Brief: I have one contact at an account: find the other leaders there who would also buy.

`count_matches` (`POST /contacts/count`)

```json
{
  "filter": {
    "domains": [
      "acme.example.com"
    ],
    "seniority": [
      "c_level",
      "vp",
      "director"
    ],
    "functions": [
      "sales_and_bizdev",
      "marketing_and_advertising"
    ]
  }
}
```

The number of leaders at the contact's `company_domain` in the functions that buy the offer, free.

`find_contacts` (`POST /contacts/search`)

```json
{
  "filter": {
    "domains": [
      "acme.example.com"
    ],
    "seniority": [
      "c_level",
      "vp",
      "director"
    ],
    "functions": [
      "sales_and_bizdev",
      "marketing_and_advertising"
    ]
  },
  "exclude_ids": [
    "per_01J9Z3K7Q8M2N4P6R8T0V2X4Y6"
  ],
  "columns": [
    "id",
    "name",
    "title",
    "company_domain",
    "seniority",
    "function"
  ],
  "limit": 10
}
```

The leaders at that domain without the contact you started from. `exclude_ids` sits beside the filter and works on count, search and export.

## Exclude a competitor and an industry

Brief: US directors and managers, but not at our competitor and not in banking.

`get_values` (`GET /contacts/schema/company_industries/values?q=bank&limit=5`)

The matching industry slugs with their labels, so the agent sends a slug the contract knows. Free.

`count_matches` (`POST /contacts/count`)

```json
{
  "filter": {
    "countries": [
      "us"
    ],
    "seniority": [
      "director",
      "manager"
    ],
    "exclude_domains": [
      "competitor.example.com"
    ],
    "exclude_industries": [
      "banking_and_lending"
    ],
    "exclude_functions": [
      "human_resources"
    ]
  }
}
```

The count after the three exclusions. Each `exclude_` key is the NOT of its twin.

`find_contacts` (`POST /contacts/search`)

```json
{
  "filter": {
    "countries": [
      "us"
    ],
    "seniority": [
      "director",
      "manager"
    ],
    "exclude_domains": [
      "competitor.example.com"
    ],
    "exclude_industries": [
      "banking_and_lending"
    ],
    "exclude_functions": [
      "human_resources"
    ]
  },
  "columns": [
    "id",
    "name",
    "title",
    "company_domain",
    "seniority"
  ],
  "limit": 10
}
```

A page with no row from the excluded domain, industry or function.

## A where clause with not_in

Brief: Engineering leaders in the United States without either of two named skills.

`count_matches` (`POST /contacts/count`)

```json
{
  "filter": {
    "countries": [
      "us"
    ],
    "functions": [
      "engineering"
    ],
    "seniority": [
      "c_level",
      "vp",
      "director"
    ],
    "where": {
      "field": "skills",
      "op": "not_in",
      "value": [
        "recruiting",
        "accounting"
      ]
    }
  }
}
```

The count with the tree applied. There is no `exclude_skills` key: a negation outside the six flat ones goes through `where` with `not_in`.

`find_contacts` (`POST /contacts/search`)

```json
{
  "filter": {
    "countries": [
      "us"
    ],
    "functions": [
      "engineering"
    ],
    "seniority": [
      "c_level",
      "vp",
      "director"
    ],
    "where": {
      "field": "skills",
      "op": "not_in",
      "value": [
        "recruiting",
        "accounting"
      ]
    }
  },
  "columns": [
    "id",
    "name",
    "title",
    "company_domain",
    "seniority"
  ],
  "limit": 10
}
```

Rows whose skills contain neither value. A tree over 32 predicates answers 422 `filter.rejected`.

## A headcount band and a funding round

Brief: C-level people at US companies of 201 to 500 staff that raised a Series B.

`get_values` (`GET /contacts/schema/company_size/values?q=201&limit=10`)

The headcount bands that match, so the agent sends a band the contract knows rather than two numbers. The funding round slugs are a frozen list on the Filters page. Free.

`count_matches` (`POST /contacts/count`)

```json
{
  "filter": {
    "countries": [
      "us"
    ],
    "seniority": [
      "c_level"
    ],
    "company_size": [
      "201-500"
    ],
    "last_round_types": [
      "series_b"
    ]
  }
}
```

The count for the band and the round together. A company with no funding on record is null, never zero, so it does not match.

`find_contacts` (`POST /contacts/search`)

```json
{
  "filter": {
    "countries": [
      "us"
    ],
    "seniority": [
      "c_level"
    ],
    "company_size": [
      "201-500"
    ],
    "last_round_types": [
      "series_b"
    ]
  },
  "columns": [
    "id",
    "name",
    "title",
    "company",
    "company_domain"
  ],
  "limit": 10
}
```

A page, or an empty `data` with a `no_rows` warning that lists the four keys and asks for one to be removed.

## A signal: a recent job change

Brief: US sales leaders who started a new job recently, because they buy in their first quarter.

`count_matches` (`POST /contacts/count`)

```json
{
  "filter": {
    "countries": [
      "us"
    ],
    "functions": [
      "sales_and_bizdev"
    ],
    "where": {
      "field": "signals",
      "op": "in",
      "value": [
        "recent_job_change"
      ]
    }
  }
}
```

The count for the signal. Signals have no flat key: they are filtered with `in` or `not_in` on `signals` inside `where`.

`find_contacts` (`POST /contacts/search`)

```json
{
  "filter": {
    "countries": [
      "us"
    ],
    "functions": [
      "sales_and_bizdev"
    ],
    "where": {
      "field": "signals",
      "op": "in",
      "value": [
        "recent_job_change"
      ]
    }
  },
  "columns": [
    "id",
    "name",
    "title",
    "company_domain",
    "signals",
    "role_since"
  ],
  "limit": 10
}
```

Rows that carry the signal, with `signals` and `role_since` on the row so the agent can read the date itself.

## At most two people per company

Brief: A software list that is not all from one account: at most two people per company.

`count_matches` (`POST /contacts/count`)

```json
{
  "filter": {
    "industries": [
      "software_development"
    ],
    "seniority": [
      "c_level",
      "vp",
      "director"
    ],
    "has_work_email": true
  }
}
```

The count of everyone who matches. The count does not apply the per-company cap: the cap belongs to the page.

`find_contacts` (`POST /contacts/search`)

```json
{
  "filter": {
    "industries": [
      "software_development"
    ],
    "seniority": [
      "c_level",
      "vp",
      "director"
    ],
    "has_work_email": true
  },
  "columns": [
    "id",
    "name",
    "title",
    "company",
    "company_domain"
  ],
  "max_rows_per_company": 2,
  "limit": 25
}
```

A page holding at most two rows for each `company_domain`. The cap applies to each page, not to the whole search.

## The second page, by cursor

Brief: Read a US audience page by page, and never show me the same person twice.

`find_contacts` (`POST /contacts/search`)

```json
{
  "filter": {
    "countries": [
      "us"
    ],
    "has_work_email": true
  },
  "columns": [
    "id",
    "name",
    "title",
    "company_domain",
    "country"
  ],
  "limit": 5
}
```

Five rows and a `page.next_cursor`. The cursor is opaque and it pins the filter, the sort tuple and the build.

`find_contacts` (`POST /contacts/search`)

```json
{
  "filter": {
    "countries": [
      "us"
    ],
    "has_work_email": true
  },
  "columns": [
    "id",
    "name",
    "title",
    "company_domain",
    "country"
  ],
  "limit": 5
}
```

The next five rows, with no id from the first page. Read pages until `next_cursor` is null. A cursor from an older build answers 400 `cursor.expired`.

## An export that gets truncated

Brief: Write me a file of US contacts with a work email, but cap this job at 25 rows.

`count_matches` (`POST /contacts/count`)

```json
{
  "filter": {
    "countries": [
      "us"
    ],
    "has_work_email": true
  }
}
```

The size of the audience, free, before any row is spent.

`start_export` (`POST /exports`)

```json
{
  "filter": {
    "countries": [
      "us"
    ],
    "has_work_email": true
  },
  "columns": [
    "id",
    "name",
    "work_email",
    "company_domain",
    "country",
    "seniority"
  ],
  "format": "csv",
  "max_rows": 25
}
```

202 with `rows_available`, `rows_to_export: 25`, `truncated: true` and `truncation_reason: "max_rows"`, plus an `export_truncated` warning. The contact credits are held, not charged.

`get_export` (`GET /exports/{export_id}`)

The job status. Poll until it is `completed`, then read `url`: a signed link on our own domain that lives 7 days from completion. An expired or gone file answers 410 with the code `export.expired`. The contact credits are charged on completion.

## Enrichment by LinkedIn URL

Brief: Fill in the record for a LinkedIn profile I already have.

`enrich_contact` (`POST /enrichments`)

```json
{
  "inputs": [
    "https://www.linkedin.com/in/sample-dana-reyes-1ifdfs"
  ],
  "columns": [
    "id",
    "name",
    "title",
    "company",
    "company_domain",
    "work_email",
    "seniority"
  ]
}
```

One result for each input, in the order they were sent, each with `input`, `matched`, `off_domain` and `contact`. A hit costs one contact credit and a miss costs nothing. v1 answers from our own store; `refresh` answers 400 `enrich.mode_unavailable`.

`enrich_contact` (`POST /enrichments`)

```json
{
  "inputs": [
    "https://www.linkedin.com/in/sample-dana-reyes-1ifdfs",
    "dana.reyes@example.com"
  ],
  "company_domain": "example.com",
  "columns": [
    "id",
    "name",
    "title",
    "company",
    "company_domain",
    "work_email"
  ]
}
```

The same call scoped to the account the people came from. A person we hold at another employer, or with no employer domain, answers `matched: false` with `off_domain: true`, costs nothing, and is listed on one `off_domain` warning. So a list sourced from one account never comes back with an email at a previous employer, an agency, or a school.

