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

# Webhooks einrichten

> Webhook-Ziele konfigurieren, Endpunkte validieren, Signaturen verifizieren und Payloads verarbeiten.

Webhooks sind die empfohlene Methode zum Empfangen von Monitor-Ergebnissen. Wenn ein Monitor auslöst, sendet Pubrio in Echtzeit eine POST-Anfrage mit einem JSON-Payload an Ihre konfigurierte URL.

## Voraussetzungen

* Ein Pubrio-API-Schlüssel mit Monitor-Zugriff
* Ein öffentlich erreichbarer HTTPS-Endpunkt (oder eine Test-URL von [usewebhook.com](https://usewebhook.com))

<Tip>
  **Schnelles Testen:** Verwenden Sie [usewebhook.com](https://usewebhook.com), um eine kostenlose temporäre Webhook-URL zu erzeugen. Sie können jeden eingehenden Payload prüfen, ohne etwas bereitstellen zu müssen.
</Tip>

***

## Schritt 1: Monitor mit Webhook-Ziel erstellen

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.pubrio.com/monitors/create \
    -H "Content-Type: application/json" \
    -H "pubrio-api-key: YOUR_API_KEY" \
    -d '{
      "name": "My First Monitor",
      "detection_mode": "signal_first",
      "signal_types": ["jobs"],
      "signal_filters": [
        {
          "signal_type": "jobs",
          "filters": {
            "locations": ["US"]
          }
        }
      ],
      "destination_type": "webhook",
      "destination_config": {
        "webhook_url": "https://usewebhook.com/YOUR_WEBHOOK_ID",
        "headers": {
          "X-Custom-Auth": "your-secret-token"
        },
        "body": {
          "pipeline": "my-webhook"
        }
      },
      "max_records_per_trigger": 5,
      "profile_id": 1
    }'
  ```

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

  response = requests.post(
      "https://api.pubrio.com/monitors/create",
      headers={
          "Content-Type": "application/json",
          "pubrio-api-key": "YOUR_API_KEY"
      },
      json={
          "name": "My First Monitor",
          "detection_mode": "signal_first",
          "signal_types": ["jobs"],
          "signal_filters": [
              {
                  "signal_type": "jobs",
                  "filters": {
                      "locations": ["US"]
                  }
              }
          ],
          "destination_type": "webhook",
          "destination_config": {
              "webhook_url": "https://usewebhook.com/YOUR_WEBHOOK_ID",
              "headers": {
                  "X-Custom-Auth": "your-secret-token"
              },
              "body": {
                  "pipeline": "my-webhook"
              }
          },
          "max_records_per_trigger": 5,
          "profile_id": 1
      }
  )

  print(response.json())
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://api.pubrio.com/monitors/create", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "pubrio-api-key": "YOUR_API_KEY"
    },
    body: JSON.stringify({
      name: "My First Monitor",
      detection_mode: "signal_first",
      signal_types: ["jobs"],
      signal_filters: [
        {
          signal_type: "jobs",
          filters: {
            locations: ["US"]
          }
        }
      ],
      destination_type: "webhook",
      destination_config: {
        webhook_url: "https://usewebhook.com/YOUR_WEBHOOK_ID",
        headers: {
          "X-Custom-Auth": "your-secret-token"
        },
        body: {
          pipeline: "my-webhook"
        }
      },
      max_records_per_trigger: 5,
      profile_id: 1
    })
  });

  console.log(await response.json());
  ```
</CodeGroup>

**Antwort:**

```json theme={null}
{
  "data": {
    "monitor_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "My First Monitor",
    "detection_mode": "signal_first",
    "destination_type": "webhook",
    "is_active": true,
    "is_paused": false,
    "masked_signature": "7••••••••••••••••8df",
    "created_at": "2026-04-06T10:00:00.000Z",
    "signature": "71a2b3c4-d5e6-f789-0abc-def123456789"
  }
}
```

Das `headers`-Objekt fügt jeder Zustellung benutzerdefinierte HTTP-Header hinzu (nützlich für die Authentifizierung). Das `body`-Objekt fügt der Wurzel des Webhook-Payloads benutzerdefinierte Felder hinzu.

<Tip>
  Speichern Sie die `signature` aus der Antwort — Sie benötigen sie, um eingehende Payloads zu verifizieren. Sie wird nur bei der Erstellung, über den Endpunkt [Signature Reveal](/de/api-reference/endpoint/monitors/signature_reveal) oder von [Monitor Lookup](/de/api-reference/endpoint/monitors/lookup) mit `is_signature_reveal: true` zurückgegeben.
</Tip>

***

## Schritt 2: Ihre Webhook-Verbindung validieren

Verwenden Sie den Endpunkt [Validate Webhook](/de/api-reference/endpoint/monitors/webhook_validate), um zu testen, dass Ihr Endpunkt erreichbar ist. Dies sendet einen **Beispiel-Payload** mit Platzhalterdaten — es werden keine Credits verbraucht, es werden keine echten Signale abgerufen.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.pubrio.com/monitors/webhook/validate \
    -H "Content-Type: application/json" \
    -H "pubrio-api-key: YOUR_API_KEY" \
    -d '{
      "monitor_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "detection_mode": "signal_first",
      "signal_types": ["jobs"],
      "signal_filters": [
        {
          "signal_type": "jobs",
          "filters": { "locations": ["US"] }
        }
      ],
      "destination_type": "webhook",
      "destination_config": {
        "webhook_url": "https://usewebhook.com/YOUR_WEBHOOK_ID",
        "headers": { "X-Custom-Auth": "your-secret-token" },
        "body": { "pipeline": "my-webhook" }
      },
      "profile_id": 1
    }'
  ```
</CodeGroup>

Eine erfolgreiche Antwort gibt sowohl den gesendeten Beispiel-Anfrage-Payload als auch die von Ihrem Endpunkt zurückgegebene Antwort zurück — so können Sie die Verbindung bestätigen, bevor Sie live gehen.

***

## Schritt 3: Mit echten Daten testen

Sobald die Verbindung validiert ist, lösen Sie mit dem Endpunkt [Process Try](/de/api-reference/endpoint/monitors/process_try) einen echten Durchlauf aus. Dieser ruft tatsächliche Signale ab und liefert sie an Ihren Webhook aus — verwenden Sie `tried_at` mit einem kürzlich vergangenen Datum, um sicherzustellen, dass Daten verfügbar sind:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.pubrio.com/monitors/process/try \
    -H "Content-Type: application/json" \
    -H "pubrio-api-key: YOUR_API_KEY" \
    -d '{
      "monitor_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "tried_at": "2026-01-01T00:00:00.000Z",
      "profile_id": 1
    }'
  ```
</CodeGroup>

<Info>
  Anders als Validate führt der Try-Endpunkt einen echten Scan aus und **verbraucht Credits**. Verwenden Sie ihn, um zu überprüfen, dass echte Payloads korrekt ankommen, und um eine schnelle Schätzung der Ergebnisse zu erhalten, bevor der geplante Scan startet.
</Info>

***

## Schritt 4: Signaturen verifizieren

Jeder Monitor hat eine eindeutige Signatur, mit der Sie überprüfen können, dass eingehende Payloads tatsächlich von Pubrio stammen.

<CodeGroup>
  ```bash cURL — Signatur anzeigen theme={null}
  curl -X POST https://api.pubrio.com/monitors/signature/reveal \
    -H "Content-Type: application/json" \
    -H "pubrio-api-key: YOUR_API_KEY" \
    -d '{
      "monitor_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "profile_id": 1
    }'
  ```
</CodeGroup>

```json theme={null}
{
  "data": {
    "monitor_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "signature": "71a2b3c4-d5e6-f789-0abc-def123456789"
  }
}
```

Vergleichen Sie diese Signatur mit der `monitor.monitor_id` in eingehenden Payloads, um die Echtheit zu verifizieren.

***

## Struktur des Webhook-Payloads

Payloads unterscheiden sich je nach `detection_mode` des Monitors:

<Tabs>
  <Tab title="Signal First">
    Im Modus `signal_first` enthält der Payload ein `signals`-Array auf oberster Ebene:

    ```json theme={null}
    {
      "monitor": {
        "monitor_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "name": "My Signal Monitor",
        "detection_mode": "signal_first",
        "signal_types": ["jobs", "news"],
        "signal_filters": [...],
        "company_filters": {...},
        "is_company_enrichment": true,
        "is_people_enrichment": true,
        "people_enrichment_configs": [...]
      },
      "metadata": {
        "total_signals": 3,
        "total_companies": 2,
        "total_people": 5
      },
      "triggered_at": "2026-04-05T20:29:43.832Z",
      "signals": [
        {
          "signal_type": "jobs",
          "signal": {
            "signal_type": "jobs",
            "job_search_id": "...",
            "companies": [
              {
                "domain_search_id": "...",
                "company_name": "...",
                "domain": "...",
                ...
              }
            ],
            ...
          },
          "companies": [
            {
              "domain_search_id": "...",
              "company_name": "...",
              "domain": "...",
              "logo_url": "...",
              "country_code": "...",
              "company_size": 5000,
              "industry": "...",
              "people": [...],
              "emails": [...],
              "phones": [...],
              ...
            }
          ]
        },
        {
          "signal_type": "news",
          "signal": {
            "signal_type": "news",
            "news_search_id": "...",
            "news_id": "...",
            "title": "...",
            "summary": "...",
            "published_at": "...",
            "source": "...",
            "category": "...",
            "companies": [...],
            ...
          },
          "companies": [...],
          ...
        },
        ...
      ]
    }
    ```

    Jeder Signal-Eintrag enthält die Signaldetails sowie die zugehörigen angereicherten Unternehmen und Personen.
  </Tab>

  <Tab title="Company First">
    Im Modus `company_first` enthält der Payload ein `companies`-Array auf oberster Ebene mit angereicherten Unternehmensdaten und verschachtelten Signalen:

    ```json theme={null}
    {
      "monitor": {
        "monitor_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "name": "My Company Monitor",
        "detection_mode": "company_first",
        "signal_types": ["jobs", "news", "advertisements"],
        "signal_filters": [...],
        "company_filters": {...},
        "is_company_enrichment": true,
        "is_people_enrichment": true,
        "people_enrichment_configs": [...]
      },
      "metadata": {
        "total_signals": 4,
        "total_companies": 2,
        "total_people": 8
      },
      "triggered_at": "2026-04-03T17:45:27.228Z",
      "companies": [
        {
          "company_name": "Acme Corp",
          "domain": "acmecorp.com",
          "domain_search_id": "...",
          "country_code": "US",
          "logo_url": "...",
          "linkedin_name": "acmecorp",
          "company_size": 5200,
          "industry": "Enterprise Software",
          "estimated_revenue": 50000000,
          "founded_year": 2010,
          "company_address": "San Francisco, CA",
          "specialties": ["SaaS", "Cloud Computing", ...],
          "linkedin_url": "https://linkedin.com/company/...",
          "locations": ["US"],
          "signals": [
            {
              "signal_type": "news",
              "signal": {
                "news_id": "...",
                "title": "Acme Corp Launches New AI Product",
                "summary": "...",
                "published_at": "2026-04-03T16:35:00.000Z",
                "source": "techcrunch.com",
                "category": "launches",
                "news_category_name": "Product Launch",
                ...
              }
            },
            {
              "signal_type": "jobs",
              "signal": {
                "job_search_id": "...",
                ...
              }
            },
            ...
          ],
          "people": [
            {
              "name": "Jane Smith",
              "title": "VP of Engineering",
              "email": "j.smith@acmecorp.com",
              ...
            },
            ...
          ],
          "emails": ["info@acmecorp.com", ...],
          "phones": ["+14155551234", ...],
          "contacts": [...],
          ...
        },
        ...
      ]
    }
    ```

    Jedes Unternehmen im Array enthält das vollständige angereicherte Profil, alle übereinstimmenden Signale und angereicherte Personenkontakte.
  </Tab>
</Tabs>

<Note>
  Benutzerdefinierte `body`-Felder aus `destination_config` erscheinen auf der Wurzelebene des Payloads (z. B. `"pipeline": "my-webhook"`, wenn in Ihrem Ziel konfiguriert).
</Note>

***

## Expansion-Signale

Neben `jobs`, `news` und `advertisements` kann ein Monitor auch **Expansion-Signale** beobachten — die datierten Belege dafür, dass ein Unternehmen in einen neuen Markt eintritt oder dort wächst. Fügen Sie `expansions` zu `signal_types` hinzu:

```json theme={null}
{
  "name": "US market entries",
  "detection_mode": "signal_first",
  "signal_types": ["expansions"],
  "signal_filters": [
    {
      "signal_type": "expansions",
      "filters": {
        "tos": ["US"],
        "stages": ["expanding", "scaling"],
        "signal_strengths": ["high", "very_high"],
        "window_days": 30
      }
    }
  ],
  "destination_type": "webhook",
  "destination_config": {
    "webhook_url": "https://usewebhook.com/YOUR_WEBHOOK_ID"
  }
}
```

Expansion-Filter verwenden das Vokabular von [Expansion Search](/de/api-reference/endpoint/expansions/market_lookup), nicht das von Jobs/News/Anzeigen — `froms` und `tos` für den Korridor, plus `stages`, `scopes`, `momentum`, `freshness`, `signal_types`, `signal_subtypes`, `signal_strengths`, `source_types` und `window_days`. Die gültigen Slugs finden Sie unter [Expansion Reference](/de/api-reference/endpoint/expansions/types).

<Note>
  Expansion-Signale werden **pro Unternehmen und Markt** gruppiert, nicht pro Signal. Tritt ein Unternehmen in zwei Märkte ein, entstehen zwei Einträge, jeder mit der eigenen Signal-Zeitleiste dieses Markts.
</Note>

### Payload für Expansion-Signale

```json theme={null}
{
  "monitor": {
    "monitor_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "US market entries",
    "detection_mode": "signal_first",
    "signal_types": ["expansions"],
    "signal_filters": [...]
  },
  "metadata": {
    "total_signals": 2,
    "total_companies": 1,
    "total_people": 0
  },
  "triggered_at": "2026-08-14T09:12:04.551Z",
  "signals": [
    {
      "signal_type": "expansions",
      "signal": {
        "signal_type": "expansions",
        "expansion_signal_id": 90211,
        "domain_search_id": "550e8400-e29b-41d4-a716-446655440002",
        "country_code": "US",
        "signal_type_slug": "HIRE",
        "signal_type_name": "Hiring",
        "signal_subtype_slug": "country_manager",
        "signal_strength_slug": "high",
        "polarity": "expansion",
        "event_date": "2026-08-13T14:00:00.000Z",
        "event_date_precision": "day",
        "source_type": "linkedin",
        "display_label": "Hired Country Manager",
        "evidence_url": "https://linkedin.com/company/example-corp",
        "metadata": {...},
        "companies": [
          {
            "domain_search_id": "550e8400-e29b-41d4-a716-446655440002",
            "company_name": "Example Corp",
            "domain": "example.com",
            "stage_name": "Expanding",
            "stage_description": "...",
            "home_country": "GB",
            "home_country_name": "United Kingdom",
            "target_country": "US",
            "target_country_name": "United States",
            "estimated_employees": 420,
            "linkedin_url": "https://linkedin.com/company/example-corp"
          }
        ]
      },
      "companies": [...]
    }
  ]
}
```

Die Bedeutung der einzelnen Felder finden Sie in der [Expansion Field Reference](/de/knowledge-base/concepts/expansion-field-reference). Um dieselben Zeilen bei Bedarf statt bei einem Trigger abzurufen, verwenden Sie [Expansion Signal Search](/de/api-reference/endpoint/expansions/signal_search).

***

## E-Mail-Ziel

Für Teams, die die Zustellung per E-Mail bevorzugen, setzen Sie `destination_type` auf `"email"`:

```json theme={null}
{
  "destination_type": "email",
  "destination_config": {
    "email": "alerts@your-company.com"
  }
}
```

<Info>
  Pubrio unterstützt White-Label-E-Mail-Zustellung für Agenturen und Teams. [Kontaktieren Sie uns](https://pubrio.com/en/get-in-touch), um mehr über die Anpassung der Absenderdomain und des Brandings zu erfahren.
</Info>

***

## Fehlerbehebung

<AccordionGroup>
  <Accordion title="Webhook empfängt keine Payloads">
    * Überprüfen Sie, dass Ihr Endpunkt öffentlich erreichbar ist (nicht hinter einer Firewall oder einem VPN)
    * Stellen Sie sicher, dass er den Statuscode `200` zurückgibt — andere Codes werden als Fehler behandelt
    * Verwenden Sie den Endpunkt [Validate Webhook](/de/api-reference/endpoint/monitors/webhook_validate), um die Konnektivität zu testen
    * Prüfen Sie [Statistic Logs](/de/api-reference/endpoint/monitors/statistics_logs) auf Fehlermeldungen und Antwortcodes
  </Accordion>

  <Accordion title="Monitor nach Fehlern pausiert">
    Wenn Ihr Webhook durchgehend Nicht-200-Codes zurückgibt, pausiert der Monitor, sobald `max_failure_trigger` aufeinanderfolgende Fehler erreicht ist. Beheben Sie das Problem und reaktivieren Sie über [Update Monitor](/de/api-reference/endpoint/monitors/update).
  </Accordion>

  <Accordion title="Doppelte Payloads">
    Wenn eine Zustellung fehlschlägt und Wiederholungsversuche konfiguriert sind, können Sie denselben Payload mehrfach erhalten. Verwenden Sie `triggered_at` oder die Log-ID, um auf Ihrer Seite zu deduplizieren.
  </Accordion>

  <Accordion title="Payload zu groß">
    Reduzieren Sie `max_records_per_trigger`, um die Anzahl der Datensätze pro Zustellung zu begrenzen. Sie können auch Ihre Filter eingrenzen, um das Volumen übereinstimmender Signale zu reduzieren.
  </Accordion>
</AccordionGroup>
