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

# Filter-Übersicht

> Wie die Pubrio-Suchfilter funktionieren — die einheitliche Filter-Engine, AND-/OR-Semantik und wann welche verwenden.

Die Such-Endpunkte von Pubrio (`/companies/search`, `/people/search`, `/companies/advertisements/search`) teilen sich eine einzige Filter-Engine. Sie stellen einen Anfrage-Body einmal zusammen, und dieselben Regeln gelten über alle Endpunkte hinweg — einschließlich der Art, wie Mehrwert-Filter kombiniert werden, wie Standorte abgeglichen werden und wie Sie den Standardoperator mit `filter_conditions` überschreiben.

## Warum eine einheitliche Filter-Engine?

<CardGroup cols={2}>
  <Card title="Ein Schema, drei Endpunkte" icon="arrows-rotate">
    Filter auf Unternehmensebene wie `technologies`, `verticals` und `founded_dates` funktionieren identisch auf `/companies/search`, `/people/search` und innerhalb von Monitor-`company_filters` — Sie lernen sie einmal.
  </Card>

  <Card title="AND/OR pro Filter" icon="code-merge">
    Der Standard ist OR (beliebiger Treffer). Heben Sie einzelne Filter auf AND (jeder muss zutreffen) an, indem Sie einen Eintrag zu `filter_conditions` hinzufügen — ohne den Rest des Bodys zu ändern.
  </Card>

  <Card title="Postgres-native Operatoren" icon="database">
    Array-Filter kompilieren zu nativen Postgres-Operatoren — `&&` (Überschneidung) für OR, `@>` (enthält) für AND. Indexfreundlich, keine anwendungsseitige Nachfilterung.
  </Card>

  <Card title="Dieselben Filter in Monitoren" icon="bell">
    Der `company_filters`-Block in [Monitoren](/de/developer-guides/introduction) akzeptiert dieselbe Form, sodass ein funktionierender Such-Payload auch ein funktionierender Monitor-Payload ist.
  </Card>
</CardGroup>

***

## Aufbau einer Suchanfrage

Jede Suchanfrage besteht aus drei Ebenen im selben JSON-Body:

| Ebene                     | Wo sie liegt                                                                                                 | Beispiele                                                                      |
| ------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ |
| Personenfilter            | Schlüssel auf oberster Ebene                                                                                 | `people_titles`, `management_levels`, `departments`, `people_locations`        |
| Unternehmensfilter        | verschachtelt unter `company_filters: {...}` (empfohlen) — auch auf oberster Ebene akzeptiert                | `technologies`, `verticals`, `founded_dates`, `employees`, `company_locations` |
| Operator-Überschreibungen | `filter_conditions`-Array (innerhalb von `company_filters`, wenn Unternehmensschlüssel überschrieben werden) | `[{ "key": "technologies", "operator": "and" }]`                               |

Eine minimale `/people/search`-Anfrage, die alle drei Ebenen nutzt:

<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`: Unternehmensschlüssel gruppiert halten

Das Wrapper-Objekt `company_filters: {...}` ist die empfohlene Art, Filter auf Unternehmensebene zu senden — es trennt visuell, welche Schlüssel die *Person* filtern und welche das *Unternehmen*, und entspricht der Form, die [Monitore](/de/developer-guides/introduction) bereits verwenden, sodass Payloads sauber zwischen Such- und Monitor-Konfigurationen übertragbar sind.

Beide Stile funktionieren; die Engine flacht die eingebettete Form vor der Verarbeitung auf die oberste Ebene ab, und **Schlüssel auf oberster Ebene gewinnen bei Konflikten**:

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

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

Wenn Sie eine `filter_conditions`-Überschreibung für einen Unternehmensschlüssel hinzufügen, platzieren Sie diese **innerhalb** von `company_filters`, damit sie mit den überschriebenen Schlüsseln zusammenbleibt.

### Dieselbe Form bei den `/search/similar`-Varianten

`POST /companies/search/similar` und `POST /people/search/similar` akzeptieren **denselben Filter-Body** wie ihre nicht-ähnlichen Gegenstücke (einschließlich des `company_filters`-Wrappers und `filter_conditions`). Jeder fügt zusätzlich einen Ähnlichkeitsschritt hinzu:

|                             | Was sie zusätzlich benötigen                                                                                               | Was Sie zusätzlich erhalten                                                                                                 |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `/companies/search/similar` | Ein Referenzunternehmen — `domain_search_id`, `domain`, `linkedin_url` oder `domains`                                      | Jedes Ergebnis erhält einen `similarity_score` (Fließkommazahl, 0–1) und Zeilen werden absteigend nach Ähnlichkeit sortiert |
| `/people/search/similar`    | Eine Referenzperson/-titel — eines von `people_titles`, `people_search_id`, `linkedin_url`, `linkedin_urls` oder `peoples` | Ebenso — `similarity_score` pro Zeile, nach Ähnlichkeit sortiert                                                            |

Die Antworthülle ist ansonsten identisch mit dem Standard-`search`-Endpunkt. Filter grenzen den Kandidatenpool ein, *bevor* die Ähnlichkeitsrangfolge angewendet wird — die Kombination von `company_locations: ["US"]` mit `/people/search/similar` liefert also die ähnlichsten US-basierten Personen zu Ihren Referenztiteln, das Muster „finde mehr Personen wie X innerhalb dieser Einschränkungen".

<Note>
  Anders als die Standard-`/search`-Endpunkte liefert `/search/similar` **keine** exakte `pagination.total_entries` — der Wert ist gedeckelt, da die Ähnlichkeitssuche Ergebnisse nach Relevanz einstuft und nur die besten Treffer anzeigt. Verwenden Sie die Ähnlichkeitssuche, um die *besten* Treffer zu finden, nicht um jeden einzelnen aufzuzählen.
</Note>

***

## AND vs. OR — die eine Entscheidung pro Filter

Mehrwert-Filter (`technologies`, `verticals`, `keywords`, `categories`, …) akzeptieren ein Array. Der Operator entscheidet, was „Treffer" bedeutet:

<Tabs>
  <Tab title="OR (Standard)">
    **Beliebiger Treffer.** Liefert Zeilen, deren Array sich mit der Eingabe überschneidet.

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

    Ein Unternehmen wird einbezogen, wenn sein Tech-Stack **mindestens eines** von `Python`, `PostgreSQL` oder `Kubernetes` enthält. Kompiliert zu Postgres `column && ARRAY[...]`.

    Verwenden, wenn: Sie breite Reichweite möchten — „interessiert an *einem beliebigen* dieser", „in *einem beliebigen* dieser Länder ansässig".
  </Tab>

  <Tab title="AND">
    **Jeder Wert muss zutreffen.** Liefert Zeilen, deren Array jeden Eingabewert enthält.

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

    Numerische Tag-IDs stammen von `GET /technologies?search_term=python` (und ähnlichen). **Kombinieren Sie `is_enable_similarity_search: true` nicht mit AND auf demselben Schlüssel** — die Ähnlichkeitssuche erweitert jeden Freitextbegriff zu vielen Tag-IDs, und `@>` verlangt dann, dass die Zeile alle enthält, was fast immer null Ergebnisse liefert.

    Ein Unternehmen wird nur einbezogen, wenn sein Tech-Stack **alle** von `[37, 152, 408]` enthält. Kompiliert zu Postgres `column @> ARRAY[...]`.

    Verwenden, wenn: Sie Präzision möchten — „nutzt *alle* dieser Technologien zusammen", „mit *allen* dieser Verticals getaggt".
  </Tab>
</Tabs>

<Note>
  Nicht in `filter_conditions` aufgeführte Filter verwenden den Standardoperator (OR innerhalb eines Arrays, AND über unterschiedliche Filterschlüssel hinweg). Sie deklarieren nur die Überschreibungen — nie die Standardwerte.
</Note>

***

## Was Sie überschreiben können

Jeder Endpunkt akzeptiert Überschreibungen für eine andere Schlüsselmenge. Die Schlüssel stammen aus dem OpenAPI-Enum jedes `*_filter_conditions`-Schemas:

<CardGroup cols={3}>
  <Card title="Unternehmens-Endpunkt" icon="building" href="/de/api-reference/endpoint/companies/search">
    `company_filter_conditions`-Schlüssel: `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="Personen-Endpunkt" icon="user" href="/de/api-reference/endpoint/people/search">
    `people_filter_conditions`-Schlüssel (delegieren an die Unternehmens-Engine): `keywords`, `verticals`, `vertical_categories`, `vertical_sub_categories`, `technologies`, `categories`, `places`, `exclude_places`, plus `social_media`.
  </Card>

  <Card title="Anzeigen-Endpunkt" icon="bullhorn" href="/de/api-reference/endpoint/companies/advertisements_search">
    `ads_filter_conditions`-Schlüssel: `target_locations`, `exclude_target_locations`. Kleinere Menge, da Anzeigen nur nach Impressionsland gefiltert werden.
  </Card>
</CardGroup>

<Tip>
  Bei Verwendung von `/people/search` verwendet `filter_conditions[].key` für Unternehmensstandorte den **bloßen** Namen aus der Unternehmens-Engine — `places`, `exclude_places` — nicht den präfixierten People-API-Namen (`company_places`). Siehe [People + Company Filters](/de/developer-guides/filters/people-with-company-filters#key-remap-reference).
</Tip>

***

## Performance-Tipps

<AccordionGroup>
  <Accordion title="Früh nach indizierten Spalten filtern" icon="bolt">
    Standorte, Mitarbeiter-Bucketwerte und `founded_dates` sind indiziert und reduzieren die Kandidatenmenge schneller als Freitext- oder Vertical-Filter. Kombinieren Sie sie mit ein oder zwei präzisen Filtern, bevor Sie zur Ähnlichkeitssuche greifen.
  </Accordion>

  <Accordion title="Große Arrays nicht übermäßig mit AND verknüpfen" icon="triangle-exclamation">
    `column @> ARRAY[a, b, c, …]` verlangt, dass jeder Wert vorhanden ist. Die Kardinalität wächst schnell — ein AND mit 10 Technologien in einer Kategorie mit durchschnittlich 3 Tech-Tags liefert fast null Zeilen und erzwingt einen vollständigen Scan. Bevorzugen Sie 2–4 Werte pro AND-Filter; wechseln Sie zu OR für explorative Abfragen.
  </Accordion>

  <Accordion title="is_enable_similarity_search für Freitext-Eingaben verwenden" icon="wand-magic-sparkles">
    Wenn Sie keine Slug-IDs (Verticals, Technologien, Kategorien) angeben können und nur Freitext-Strings haben, setzen Sie `is_enable_similarity_search: true` und `similarity_score: 0.7`. Die Engine löst Treffer auf, bevor der Filter angewendet wird — deutlich günstiger als das Durchsuchen von Text.
  </Accordion>

  <Accordion title="Bereiche statt Enum-Listen für Größe und Umsatz bevorzugen" icon="arrows-left-right">
    `employees: [[201, 500], [501, 1000]]` (ein Array von Buckets) und `revenues: [1000000, 5000000]` (ein einzelner Min-/Max-Bereich) sind schneller und idiomatischer als lange ID-Listen.
  </Accordion>
</AccordionGroup>

***

## Filter für Werbeaktivität

`/companies/search` kann nach dem Werbeprofil eines Unternehmens filtern — wie viele Anzeigen es schaltet, ob welche aktuell aktiv sind, welche Plattformen und Formate es nutzt und wie es im Vergleich zu anderen Werbetreibenden in einem bestimmten Land rangiert. `POST /companies/advertisements/search` akzeptiert jeden dieser Filter ebenfalls (`advertisement_active_ads`, `advertisement_running_ads`, `advertisement_total_ads`, `advertisement_platform_count`, `advertisement_format_count`, `advertisement_impressions_estimate`, `advertisement_formats`, `advertisement_country_activity`) — eine Anzeige wird einbezogen, wenn das zugehörige Unternehmen die Bedingung erfüllt.

| Filter                                                                             | Form                                                                                                                                                   | Geltungsbereich |
| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------- |
| `advertisement_active_ads`, `advertisement_running_ads`, `advertisement_total_ads` | `[min, max]`-Bereich                                                                                                                                   | Alle Länder     |
| `advertisement_platform_count`, `advertisement_format_count`                       | `[min, max]`-Bereich                                                                                                                                   | Alle Länder     |
| `advertisement_impressions_estimate`                                               | `[min, max]`-Bereich                                                                                                                                   | Alle Länder     |
| `advertisement_formats`                                                            | Array — `image`, `video`, `text`, `carousel`, `dynamic_product`, `document`, `message`, `event`, `article`, `spotlight`, `follow`, `job`, `engagement` | Alle Länder     |
| `advertisement_platforms`                                                          | Array — `linkedin`, `facebook`, `google`, `tiktok`, `apple` (`meta` als Alias für `facebook` akzeptiert)                                               | Alle Länder     |
| `advertisement_publisher_platforms`, `advertisement_exclude_publisher_platforms`   | Array — `facebook`, `instagram`, `messenger`, `threads`, `audience_network`                                                                            | Alle Länder     |
| `advertisement_status`                                                             | Array — `currently_running` (hat erfasste Anzeigen), `active_last_30_min` (Anzeigendatensätze haben sich in den letzten 30 Minuten geändert)           | Alle Länder     |
| `advertisement_country_activity`                                                   | Objekt, siehe unten                                                                                                                                    | Ein Land        |

Verwenden Sie `null` für eine offene Grenze — `[1, null]` bedeutet „mindestens 1", `[null, 500]` bedeutet „500 oder weniger".

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

### Rangfolge innerhalb eines Landes

`advertisement_country_activity` bezieht Rang, Perzentil und Volumen-Score jeweils auf ein Land — der Anzeigenrang eines Unternehmens in den USA sagt nichts über seinen Rang in Deutschland aus, daher ist `country` erforderlich:

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

<Warning>
  **`rank` zählt vom größten Werbetreibenden abwärts, wie bei einem Rennen.** `1` ist der größte Werbetreibende in diesem Land, und die Zahl *steigt*, während das Werbevolumen *sinkt*. Um die **größten** Werbetreibenden zu finden, filtern Sie `rank` mit einer **niedrigen** Obergrenze — `[null, 500]` sind die Top 500. Ein Filter von `[500, null]` findet alle **außerhalb** der Top 499, das Gegenteil von „großer Werbetreibender". Wenn Sie eine skalenunabhängige Version möchten, die unabhängig von der Anzahl der Werbetreibenden in diesem Land gleich funktioniert, verwenden Sie stattdessen `percentile` — sie läuft in die andere Richtung, sodass eine **höhere** Zahl einen **größeren** Werbetreibenden bedeutet: `[90, null]` sind die Top 10 %.
</Warning>

Kombinieren Sie `advertisement_country_activity` mit den obigen länderübergreifenden Filtern in derselben Anfrage — zum Beispiel „unter den Top 500 in den USA rangiert und unternehmensweit mindestens 100 aktive Anzeigen":

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

***

## Nächste Schritte

<CardGroup cols={2}>
  <Card title="filter_conditions" icon="code-merge" href="/de/developer-guides/filters/filter-conditions">
    Referenzseite — jeder unterstützte Schlüssel, jeder Standard und kopierbare AND-/OR-Rezepte.
  </Card>

  <Card title="People + Company Filters" icon="users-rectangle" href="/de/developer-guides/filters/people-with-company-filters">
    Verwenden Sie jeden Unternehmensfilter innerhalb von `/people/search`. Die Hauptfunktion der einheitlichen Engine.
  </Card>

  <Card title="Company Search reference" icon="building" href="/de/api-reference/endpoint/companies/search">
    Vollständiges Anfrage-/Antwortschema für `/companies/search`.
  </Card>

  <Card title="People Search reference" icon="user" href="/de/api-reference/endpoint/people/search">
    Vollständiges Anfrage-/Antwortschema für `/people/search`.
  </Card>
</CardGroup>

<Note>
  Suchen Sie die Anleitung zum dashboardseitigen Filtern? Siehe [Filtering & Exporting Contacts](/de/knowledge-base/concepts/search-filters) in der Knowledge Base.
</Note>
