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

# People + Company Filters

> Combine people-level and company-level filters in a single /people/search call — same filter engine as /companies/search.

<Note>
  `POST /people/search` accepts every company filter that `POST /companies/search` accepts. You no longer need to pre-fetch companies, collect their IDs, and feed them into a second people query — one request does both layers.
</Note>

## Two parameter families, one body

A `/people/search` request body is split conceptually into two filter families. They live at the same level in the JSON, and you mix them freely.

<Tabs>
  <Tab title="People-level">
    Filter on attributes of the *person*:

    | Parameter              | Description                                          |
    | ---------------------- | ---------------------------------------------------- |
    | `people_titles`        | Job titles (free text or slug)                       |
    | `management_levels`    | `founder`, `c_suite`, `vp`, `director`, `manager`, … |
    | `departments`          | `master_engineering`, `master_sales`, …              |
    | `department_functions` | Sub-department / function slugs                      |
    | `people_locations`     | Country codes for the person's location              |
    | `people_groups`        | Saved group IDs                                      |
    | `peoples`              | Specific `people_search_id` values                   |
    | `linkedin_urls`        | Person LinkedIn URLs                                 |
    | `social_media`         | Per-network social-media handles                     |
  </Tab>

  <Tab title="Company-level">
    Filter on attributes of the *company* the person works at — same names as `/companies/search`, with a small set of `company_`-prefixed location keys:

    | Parameter                   | Description                                                |
    | --------------------------- | ---------------------------------------------------------- |
    | `technologies`              | Technology slug IDs the company uses                       |
    | `categories`                | Category slug IDs                                          |
    | `verticals`                 | Vertical slug IDs                                          |
    | `vertical_categories`       | Vertical category slug IDs                                 |
    | `vertical_sub_categories`   | Vertical sub-category slug IDs                             |
    | `keywords`                  | Free-text keywords matched against the company description |
    | `founded_dates`             | Founded-year range, e.g. `[2015, 2023]`                    |
    | `employees`                 | Employee buckets, e.g. `[[100, 500], [501, 1000]]`         |
    | `revenues`                  | Revenue buckets in USD                                     |
    | `company_locations`         | Country codes for the company HQ                           |
    | `company_exclude_locations` | Country codes to exclude                                   |
    | `company_places`            | City / region names to include                             |
    | `company_exclude_places`    | City / region names to exclude                             |
    | `companies`                 | Specific `domain_search_id` values                         |
    | `domains`                   | Specific company domains                                   |
    | `company_linkedin_urls`     | Company LinkedIn URLs                                      |
  </Tab>
</Tabs>

<Note>
  The `company_` prefix exists only on the location/place filters because the bare `places` / `locations` names are already used for the *person's* address. Everything else uses the bare company name (`technologies`, not `company_technologies`).
</Note>

***

## Build a query in four steps

<Steps>
  <Step title="Decide the people predicate">
    Who, exactly? Title, seniority, department, country. Keep this layer at the **top level** of the body — the company predicate usually does the precision work.
  </Step>

  <Step title="Decide the company predicate">
    Which companies do they need to work at? Industry, size, founded year, HQ country, technology stack. Group these under a **`company_filters: {...}`** object so it's obvious which layer each key belongs to.
  </Step>

  <Step title="Pick AND/OR per filter via filter_conditions">
    For any multi-value filter that needs precision (e.g., "uses *all* of these techs"), add an entry to `filter_conditions` *inside* `company_filters`. Defaults are OR.
  </Step>

  <Step title="Send the request">
    `POST /people/search`. Both styles are accepted, but `company_filters: {...}` reads cleaner and matches the [Monitors](/en/developer-guides/introduction) payload shape.
  </Step>
</Steps>

### Complete example

The query: VPs of Engineering or CTOs at US-based mid-market companies founded between 2015 and 2023, employing 100-5,000 people, that use *both* Kubernetes and Docker, but excluding companies HQ'd in San Francisco.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.pubrio.com/people/search \
    -H "Content-Type: application/json" \
    -H "pubrio-api-key: YOUR_API_KEY" \
    -d '{
      "people_titles": ["VP of Engineering", "CTO"],

      "company_filters": {
        "company_locations": ["US"],
        "company_exclude_places": ["San Francisco"],
        "founded_dates": [2010, 2024],
        "employees": [[100, 500], [501, 1000], [1001, 5000]],
        "technologies": ["Kubernetes", "Docker"],
        "is_enable_similarity_search": true
      },

      "per_page": 25,
      "page": 1
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.pubrio.com/people/search",
      headers={
          "Content-Type": "application/json",
          "pubrio-api-key": "YOUR_API_KEY",
      },
      json={
          "people_titles": ["VP of Engineering", "CTO"],

          "company_filters": {
              "company_locations": ["US"],
              "company_exclude_places": ["San Francisco"],
              "founded_dates": [2010, 2024],
              "employees": [[100, 500], [501, 1000], [1001, 5000]],
              "technologies": ["Kubernetes", "Docker"],
              "is_enable_similarity_search": True,
          },

          "per_page": 25,
          "page": 1,
      },
  )
  print(response.json())
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://api.pubrio.com/people/search", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "pubrio-api-key": "YOUR_API_KEY",
    },
    body: JSON.stringify({
      people_titles: ["VP of Engineering", "CTO"],

      company_filters: {
        company_locations: ["US"],
        company_exclude_places: ["San Francisco"],
        founded_dates: [2010, 2024],
        employees: [[100, 500], [501, 1000], [1001, 5000]],
        technologies: ["Kubernetes", "Docker"],
        is_enable_similarity_search: true,
      },

      per_page: 25,
      page: 1,
    }),
  });
  console.log(await response.json());
  ```
</CodeGroup>

***

## Key remap reference

When `/people/search` hands company filters to the shared engine, the location/place keys are renamed to their bare forms. The bare names are what the engine — and `filter_conditions[].key` — actually see:

| You send (people-API name)                                                                                                                        | Engine sees (company-API name) |
| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ |
| `company_locations`                                                                                                                               | `locations`                    |
| `company_exclude_locations`                                                                                                                       | `exclude_locations`            |
| `company_places`                                                                                                                                  | `places`                       |
| `company_exclude_places`                                                                                                                          | `exclude_places`               |
| `technologies`, `verticals`, `vertical_categories`, `vertical_sub_categories`, `categories`, `keywords`, `founded_dates`, `employees`, `revenues` | passed through unchanged       |

This is why `filter_conditions[].key` for company-level locations uses the bare names:

```json theme={null}
{
  "company_places": ["New York", "Boston"],
  "filter_conditions": [
    { "key": "places", "operator": "and" }
  ]
}
```

<Warning>
  `{ "key": "company_places", "operator": "and" }` is silently ignored — the engine doesn't recognise the prefixed name. Always reference the engine name in `filter_conditions`.
</Warning>

***

## Joins behind the scenes

Adding *any* company-level filter switches the people-to-company join from `LEFT JOIN` to `INNER JOIN`. People without a recognised company on file are excluded from the result, even when they match every people-level filter.

<Info>
  If your search drops to zero rows the moment you add `company_locations` or `technologies`, check whether your dataset has companies linked to the people you expect. The engine prefers correctness over recall here — it never invents companies to satisfy the filter.
</Info>

You'll see this same join behaviour reflected in the response: every returned person includes a populated `company` object whenever any company filter was applied.

***

## Common patterns

<AccordionGroup>
  <Accordion title="Account-Based Marketing (ABM)" icon="bullseye">
    Target a fixed list of companies (`companies` or `domains`), then layer on people-level filters to find the right buyers inside each one.

    ```json theme={null}
    {
      "people_titles": ["VP Marketing", "CMO"],
      "management_levels": ["vp", "c_suite"],
      "company_filters": {
        "companies": ["67c4696b-…", "f1e2d3c4-…", "0a9b8c7d-…"]
      }
    }
    ```
  </Accordion>

  <Accordion title="Ideal Customer Profile (ICP) discovery" icon="user-plus">
    Describe the company shape, not specific accounts. Use ranges and verticals — the engine returns the people that fit.

    ```json theme={null}
    {
      "people_titles": ["Head of Engineering"],
      "company_filters": {
        "verticals": [12, 47],
        "company_locations": ["US", "CA"],
        "founded_dates": [2015, 2023],
        "employees": [[51, 200], [201, 500]],
        "filter_conditions": [
          { "key": "verticals", "operator": "and" }
        ]
      }
    }
    ```
  </Accordion>

  <Accordion title="Technology-driven prospecting" icon="microchip">
    Find buyers at companies running a specific stack. AND on `technologies` is the typical override.

    ```json theme={null}
    {
      "people_titles": ["RevOps", "Sales Operations"],
      "departments": ["master_sales"],
      "company_filters": {
        "technologies": [114, 287, 452],
        "filter_conditions": [
          { "key": "technologies", "operator": "and" }
        ]
      }
    }
    ```
  </Accordion>

  <Accordion title="Competitor displacement" icon="arrows-rotate">
    Find decision-makers at companies that use a competitor's product (one tech) but not yours (excluded via `categories` or a separate filter pass).

    ```json theme={null}
    {
      "people_titles": ["VP Sales"],
      "management_levels": ["vp"],
      "company_filters": {
        "technologies": [287]
      }
    }
    ```

    Then re-run with `technologies: [114]` (your product's tag ID) and diff client-side.
  </Accordion>
</AccordionGroup>

***

## Next steps

<CardGroup cols={2}>
  <Card title="filter_conditions" icon="code-merge" href="/en/developer-guides/filters/filter-conditions">
    Full reference — every key, every default, copyable AND/OR recipes.
  </Card>

  <Card title="Filters Overview" icon="filter" href="/en/developer-guides/filters/overview">
    The mental model behind the unified filter engine.
  </Card>

  <Card title="People Search reference" icon="user" href="/en/api-reference/endpoint/people/search">
    Full request/response schema for `/people/search`.
  </Card>

  <Card title="Company Search reference" icon="building" href="/en/api-reference/endpoint/companies/search">
    Full request/response schema for `/companies/search`.
  </Card>
</CardGroup>
