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

# Visão Geral de Filtros

> Como funcionam os filtros de busca da Pubrio — o mecanismo de filtro unificado, a semântica AND/OR e quando usar cada um.

Os endpoints de busca da Pubrio (`/companies/search`, `/people/search`, `/companies/advertisements/search`) compartilham um único mecanismo de filtro. Você compõe um corpo de requisição uma vez e as mesmas regras se aplicam em todos os endpoints — incluindo a forma como os filtros multivalorados se combinam, como as localizações são comparadas e como você substitui o operador padrão com `filter_conditions`.

## Por que um mecanismo de filtro unificado?

<CardGroup cols={2}>
  <Card title="Um esquema, três endpoints" icon="arrows-rotate">
    Filtros em nível de empresa como `technologies`, `verticals` e `founded_dates` funcionam de forma idêntica em `/companies/search`, `/people/search` e dentro de `company_filters` em Monitores — você aprende uma vez.
  </Card>

  <Card title="AND/OR por filtro" icon="code-merge">
    O padrão é OR (corresponde a qualquer). Promova filtros individuais para AND (corresponde a todos) adicionando uma entrada a `filter_conditions` — sem tocar no restante do corpo.
  </Card>

  <Card title="Operadores nativos do Postgres" icon="database">
    Os filtros de array são compilados para operadores nativos do Postgres — `&&` (sobreposição) para OR, `@>` (contém) para AND. Compatível com índices, sem pós-filtragem no lado da aplicação.
  </Card>

  <Card title="Os mesmos filtros em Monitores" icon="bell">
    O bloco `company_filters` em [Monitores](/pt/developer-guides/introduction) aceita o mesmo formato, então um payload de busca funcional também é um payload de monitor funcional.
  </Card>
</CardGroup>

***

## Anatomia de uma requisição de busca

Toda requisição de busca é construída a partir de três camadas no mesmo corpo JSON:

| Camada                    | Onde fica                                                                               | Exemplos                                                                       |
| ------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| Filtros de pessoas        | chaves de nível superior                                                                | `people_titles`, `management_levels`, `departments`, `people_locations`        |
| Filtros de empresa        | aninhados sob `company_filters: {...}` (recomendado) — também aceitos no nível superior | `technologies`, `verticals`, `founded_dates`, `employees`, `company_locations` |
| Substituições de operador | array `filter_conditions` (dentro de `company_filters` ao substituir chaves de empresa) | `[{ "key": "technologies", "operator": "and" }]`                               |

Uma requisição mínima a `/people/search` que usa as três camadas:

<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": {
        "technologies": ["Kubernetes", "Docker"],
        "is_enable_similarity_search": true,
        "company_locations": ["US"]
      },
      "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": {
              "technologies": ["Kubernetes", "Docker"],
              "is_enable_similarity_search": True,
              "company_locations": ["US"],
          },
          "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: {
        technologies: ["Kubernetes", "Docker"],
        is_enable_similarity_search: true,
        company_locations: ["US"],
      },
      per_page: 25,
      page: 1,
    }),
  });
  console.log(await response.json());
  ```
</CodeGroup>

***

## `company_filters`: mantenha as chaves de empresa agrupadas

O objeto wrapper `company_filters: {...}` é a forma recomendada de enviar filtros em nível de empresa — ele separa visualmente quais chaves filtram a *pessoa* das que filtram a *empresa*, e corresponde ao formato que os [Monitores](/pt/developer-guides/introduction) já usam, de modo que os payloads são transferidos sem atrito entre configurações de busca e de monitor.

Os dois estilos funcionam; o mecanismo achata a forma agrupada para o nível superior antes de processar, e **as chaves de nível superior prevalecem em caso de conflito**:

<CodeGroup>
  ```json Wrapped (recommended) theme={null}
  {
    "people_titles": ["VP of Engineering"],
    "company_filters": {
      "technologies": [37, 152],
      "founded_dates": [2015, 2023],
      "company_locations": ["US"]
    }
  }
  ```

  ```json Flat (also works) theme={null}
  {
    "people_titles": ["VP of Engineering"],
    "technologies": [37, 152],
    "founded_dates": [2015, 2023],
    "company_locations": ["US"]
  }
  ```
</CodeGroup>

Quando você adicionar uma substituição em `filter_conditions` para uma chave em nível de empresa, coloque-a **dentro** de `company_filters`, para que ela viaje junto com as chaves que substitui.

### Mesmo formato nas variantes `/search/similar`

`POST /companies/search/similar` e `POST /people/search/similar` aceitam o **mesmo corpo de filtro** que suas contrapartes não similares (incluindo o wrapper `company_filters` e `filter_conditions`). Cada uma adiciona uma etapa de similaridade por cima:

|                             | O que precisam a mais                                                                                                     | O que você ganha a mais                                                                                         |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `/companies/search/similar` | Uma empresa de referência — `domain_search_id`, `domain`, `linkedin_url`, ou `domains`                                    | Cada resultado recebe um `similarity_score` (float, 0-1) e as linhas são ordenadas por similaridade decrescente |
| `/people/search/similar`    | Uma pessoa/cargo de referência — um de `people_titles`, `people_search_id`, `linkedin_url`, `linkedin_urls`, ou `peoples` | O mesmo — `similarity_score` por linha, ordenado por similaridade                                               |

O envelope de resposta é idêntico ao do endpoint `search` padrão, fora isso. Os filtros restringem o conjunto de candidatos *antes* de a classificação por similaridade ser aplicada — então combinar `company_locations: ["US"]` com `/people/search/similar` retorna as pessoas mais próximas baseadas nos EUA em relação aos seus cargos de referência, o que é o padrão "encontrar mais pessoas como X dentro destas restrições".

<Note>
  Ao contrário dos endpoints `/search` padrão, `/search/similar` **não** retorna um `pagination.total_entries` exato — o valor é limitado porque a busca por similaridade classifica os resultados por relevância e só exibe as melhores correspondências. Use a busca por similaridade para encontrar as *melhores* correspondências, não para enumerar todas elas.
</Note>

***

## AND vs OR — a única decisão que você toma por filtro

Filtros multivalorados (`technologies`, `verticals`, `keywords`, `categories`, …) aceitam um array. O operador decide o que "corresponder" significa:

<Tabs>
  <Tab title="OR (padrão)">
    **Corresponde a qualquer valor.** Retorna linhas cujo array se sobrepõe à entrada.

    ```json theme={null}
    {
      "technologies": ["Python", "PostgreSQL", "Kubernetes"],
      "is_enable_similarity_search": true
    }
    ```

    Uma empresa é incluída se a sua pilha de tecnologia contiver **pelo menos uma** de `Python`, `PostgreSQL` ou `Kubernetes`. Compila para o Postgres `column && ARRAY[...]`.

    Use quando: você quer alcance amplo — "interessado em *qualquer* uma destas", "localizada em *qualquer* um destes países".
  </Tab>

  <Tab title="AND">
    **Corresponde a todos os valores.** Retorna linhas cujo array contém todos os valores de entrada.

    ```json theme={null}
    {
      "technologies": [37, 152, 408],
      "filter_conditions": [
        { "key": "technologies", "operator": "and" }
      ]
    }
    ```

    IDs numéricos de tag vêm de `GET /technologies?search_term=python` (e similares). **Não combine `is_enable_similarity_search: true` com AND na mesma chave** — a similaridade expande cada termo em texto livre em vários IDs de tag, e o `@>` então exige que a linha contenha todos eles, o que quase sempre retorna zero.

    Uma empresa é incluída somente se a sua pilha de tecnologia contiver **todos** de `[37, 152, 408]`. Compila para o Postgres `column @> ARRAY[...]`.

    Use quando: você quer precisão — "usa *todas* estas tecnologias juntas", "marcada com *todas* estas verticais".
  </Tab>
</Tabs>

<Note>
  Filtros não listados em `filter_conditions` usam o operador padrão (OR dentro de um array, AND entre chaves de filtro distintas). Você só declara as substituições — nunca os padrões.
</Note>

***

## O que você pode substituir

Cada endpoint aceita substituições para um conjunto diferente de chaves. As chaves vêm do enum OpenAPI em cada esquema `*_filter_conditions`:

<CardGroup cols={3}>
  <Card title="Endpoint de empresa" icon="building" href="/pt/api-reference/endpoint/companies/search">
    Chaves de `company_filter_conditions`: `keywords`, `verticals`, `vertical_categories`, `vertical_sub_categories`, `technologies`, `categories`, `advertisement_target_locations`, `advertisement_exclude_target_locations`, `advertisement_search_terms`, `places`, `exclude_places`, `job_exclude_locations`.
  </Card>

  <Card title="Endpoint de pessoas" icon="user" href="/pt/api-reference/endpoint/people/search">
    Chaves de `people_filter_conditions` (delegam ao mecanismo de empresa): `keywords`, `verticals`, `vertical_categories`, `vertical_sub_categories`, `technologies`, `categories`, `places`, `exclude_places`, além de `social_media`.
  </Card>

  <Card title="Endpoint de anúncios" icon="bullhorn" href="/pt/api-reference/endpoint/companies/advertisements_search">
    Chaves de `ads_filter_conditions`: `target_locations`, `exclude_target_locations`. Conjunto menor porque os anúncios só filtram por país de impressão.
  </Card>
</CardGroup>

<Tip>
  Ao usar `/people/search`, o `filter_conditions[].key` para localizações em nível de empresa usa o nome **puro** do mecanismo de empresa — `places`, `exclude_places` — e não o nome prefixado da API de pessoas (`company_places`). Veja [Filtros de Pessoas + Empresa](/pt/developer-guides/filters/people-with-company-filters#key-remap-reference).
</Tip>

***

## Dicas de desempenho

<AccordionGroup>
  <Accordion title="Filtre cedo em colunas indexadas" icon="bolt">
    Localizações, faixas de funcionários e `founded_dates` são indexados e reduzem o conjunto de candidatos mais rápido do que filtros de texto livre ou de vertical. Combine-os com um ou dois filtros precisos antes de recorrer à busca por similaridade.
  </Accordion>

  <Accordion title="Não abuse do AND em arrays grandes" icon="triangle-exclamation">
    `column @> ARRAY[a, b, c, …]` exige que todo valor esteja presente. A cardinalidade cresce rápido — um AND com 10 tecnologias em uma categoria com média de 3 tags de tecnologia retorna quase nenhuma linha e força uma varredura completa. Prefira 2-4 valores por filtro AND; mude para OR em consultas exploratórias.
  </Accordion>

  <Accordion title="Use is_enable_similarity_search para entrada em texto livre" icon="wand-magic-sparkles">
    Se você não pode fornecer IDs de slug (verticais, tecnologias, categorias) e só tem strings em texto livre, defina `is_enable_similarity_search: true` e `similarity_score: 0.7`. O mecanismo resolve as correspondências antes de aplicar o filtro — muito mais barato do que varrer texto.
  </Accordion>

  <Accordion title="Prefira faixas em vez de listas de enum para porte e receita" icon="arrows-left-right">
    `employees: [[201, 500], [501, 1000]]` (um array de faixas) e `revenues: [1000000, 5000000]` (uma única faixa mín/máx) são mais rápidos e mais idiomáticos do que listas longas de IDs.
  </Accordion>
</AccordionGroup>

***

## Filtros de atividade publicitária

`/companies/search` pode filtrar pela pegada publicitária de uma empresa — quantos anúncios ela veicula, se algum está ativo no momento, quais plataformas e formatos ela usa, e como ela se classifica em relação a outros anunciantes em um determinado país. `POST /companies/advertisements/search` também aceita cada um desses filtros (`advertisement_active_ads`, `advertisement_running_ads`, `advertisement_total_ads`, `advertisement_platform_count`, `advertisement_format_count`, `advertisement_impressions_estimate`, `advertisement_formats`, `advertisement_country_activity`) — um anúncio é incluído se a empresa proprietária atender ao limite.

| Filtro                                                                             | Formato                                                                                                                                                | Escopo          |
| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------- |
| `advertisement_active_ads`, `advertisement_running_ads`, `advertisement_total_ads` | faixa `[min, max]`                                                                                                                                     | Todos os países |
| `advertisement_platform_count`, `advertisement_format_count`                       | faixa `[min, max]`                                                                                                                                     | Todos os países |
| `advertisement_impressions_estimate`                                               | faixa `[min, max]`                                                                                                                                     | Todos os países |
| `advertisement_formats`                                                            | array — `image`, `video`, `text`, `carousel`, `dynamic_product`, `document`, `message`, `event`, `article`, `spotlight`, `follow`, `job`, `engagement` | Todos os países |
| `advertisement_platforms`                                                          | array — `linkedin`, `facebook`, `google`, `tiktok`, `apple` (`meta` aceito como alias de `facebook`)                                                   | Todos os países |
| `advertisement_publisher_platforms`, `advertisement_exclude_publisher_platforms`   | array — `facebook`, `instagram`, `messenger`, `threads`, `audience_network`                                                                            | Todos os países |
| `advertisement_status`                                                             | array — `currently_running` (tem anúncios registrados), `active_last_30_min` (registros de anúncio alterados nos últimos 30 minutos)                   | Todos os países |
| `advertisement_country_activity`                                                   | objeto, veja abaixo                                                                                                                                    | Um país         |

Use `null` para um limite aberto — `[1, null]` significa "pelo menos 1", `[null, 500]` significa "500 ou menos".

```json theme={null}
{
  "advertisement_active_ads": [1, null],
  "advertisement_formats": ["video"]
}
```

### Classificação dentro de um país

`advertisement_country_activity` restringe a classificação, o percentil e a pontuação de volume a um país por vez — a classificação de anúncios de uma empresa nos EUA não diz nada sobre sua classificação na Alemanha, então `country` é obrigatório:

```json theme={null}
{
  "advertisement_country_activity": {
    "country": "US",
    "rank": [null, 500]
  }
}
```

<Warning>
  **`rank` conta de forma decrescente a partir do maior anunciante, como em uma corrida.** `1` é o maior anunciante naquele país, e o número *aumenta* conforme o volume publicitário *diminui*. Para encontrar os **maiores** anunciantes, filtre `rank` com um limite superior **baixo** — `[null, 500]` são os 500 primeiros. Filtrar `[500, null]` encontra todos os que estão **fora** dos 499 primeiros, o que é o oposto de "grande anunciante". Se você quiser uma versão livre de escala que funcione da mesma forma independentemente de quantos anunciantes existem naquele país, use `percentile` em vez disso — ele funciona na direção oposta, então um número **maior** significa um anunciante **maior**: `[90, null]` são os 10% principais.
</Warning>

Combine `advertisement_country_activity` com os filtros de todos os países acima na mesma requisição — por exemplo, "classificado entre os 500 primeiros nos EUA, e com pelo menos 100 anúncios ativos em toda a empresa":

```json theme={null}
{
  "advertisement_country_activity": { "country": "US", "rank": [null, 500] },
  "advertisement_active_ads": [100, null]
}
```

***

## Próximos passos

<CardGroup cols={2}>
  <Card title="filter_conditions" icon="code-merge" href="/pt/developer-guides/filters/filter-conditions">
    Página de referência — cada chave suportada, cada padrão, e receitas AND/OR copiáveis.
  </Card>

  <Card title="Filtros de Pessoas + Empresa" icon="users-rectangle" href="/pt/developer-guides/filters/people-with-company-filters">
    Use qualquer filtro de empresa dentro de `/people/search`. O principal novo recurso do mecanismo unificado.
  </Card>

  <Card title="Referência de Company Search" icon="building" href="/pt/api-reference/endpoint/companies/search">
    Esquema completo de requisição/resposta para `/companies/search`.
  </Card>

  <Card title="Referência de People Search" icon="user" href="/pt/api-reference/endpoint/people/search">
    Esquema completo de requisição/resposta para `/people/search`.
  </Card>
</CardGroup>

<Note>
  Procurando o passo a passo de filtragem no painel? Veja [Filtragem e Exportação de Contatos](/pt/knowledge-base/concepts/search-filters) na Base de Conhecimento.
</Note>
