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

# Configurer des webhooks

> Configurez des destinations de webhook, validez des points de terminaison, vérifiez des signatures et gérez des charges utiles.

Les webhooks sont le moyen recommandé pour recevoir les résultats d'un monitor. Lorsqu'un monitor se déclenche, Pubrio envoie une requête POST avec une charge utile JSON à l'URL que vous avez configurée — en temps réel.

## Prérequis

* Une clé API Pubrio avec accès aux monitors
* Un point de terminaison HTTPS accessible publiquement (ou une URL de test depuis [usewebhook.com](https://usewebhook.com))

<Tip>
  **Test rapide :** utilisez [usewebhook.com](https://usewebhook.com) pour générer une URL de webhook temporaire et gratuite. Vous pouvez inspecter chaque charge utile entrante sans rien déployer.
</Tip>

***

## Étape 1 : créer un Monitor avec une destination webhook

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

**Réponse :**

```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"
  }
}
```

L'objet `headers` ajoute des en-têtes HTTP personnalisés à chaque envoi (utile pour l'authentification). L'objet `body` ajoute des champs personnalisés à la racine de la charge utile du webhook.

<Tip>
  Conservez le `signature` renvoyé dans la réponse — vous en aurez besoin pour vérifier les charges utiles entrantes. Il n'est renvoyé qu'à la création, via le point de terminaison [Signature Reveal](/fr/api-reference/endpoint/monitors/signature_reveal), ou depuis [Monitor Lookup](/fr/api-reference/endpoint/monitors/lookup) avec `is_signature_reveal: true`.
</Tip>

***

## Étape 2 : valider votre connexion webhook

Utilisez le point de terminaison [Validate Webhook](/fr/api-reference/endpoint/monitors/webhook_validate) pour tester que votre point de terminaison est joignable. Cela envoie une **charge utile d'exemple** avec des données de substitution — aucun crédit n'est consommé, aucun signal réel n'est récupéré.

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

Une réponse réussie renvoie la charge utile d'exemple qui a été envoyée et la réponse que votre point de terminaison a retournée — pour que vous puissiez confirmer que la connexion fonctionne avant de passer en production.

***

## Étape 3 : tester avec des données réelles

Une fois la connexion validée, déclenchez une exécution réelle avec le point de terminaison [Process Try](/fr/api-reference/endpoint/monitors/process_try). Cela récupère de vrais signaux et les livre à votre webhook — utilisez `tried_at` avec une date passée récente pour vous assurer que des données sont disponibles :

<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>
  Contrairement à validate, le point de terminaison try exécute un vrai scan et **consomme des crédits**. Utilisez-le pour vérifier que les charges utiles réelles arrivent correctement et obtenir une estimation rapide des résultats avant le déclenchement du scan planifié.
</Info>

***

## Étape 4 : vérifier les signatures

Chaque monitor dispose d'une signature unique permettant de vérifier que les charges utiles entrantes proviennent bien de Pubrio.

<CodeGroup>
  ```bash cURL — Reveal Signature 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"
  }
}
```

Comparez cette signature au `monitor.monitor_id` des charges utiles entrantes pour en vérifier l'authenticité.

***

## Structure de la charge utile du webhook

Les charges utiles diffèrent selon le `detection_mode` du monitor :

<Tabs>
  <Tab title="Signal First">
    En mode `signal_first`, la charge utile contient un tableau `signals` de premier niveau :

    ```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": [...],
          ...
        },
        ...
      ]
    }
    ```

    Chaque entrée de signal contient les détails du signal ainsi que les entreprises et personnes enrichies associées.
  </Tab>

  <Tab title="Company First">
    En mode `company_first`, la charge utile contient un tableau `companies` de premier niveau, avec des données d'entreprise enrichies et des signaux imbriqués :

    ```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": [...],
          ...
        },
        ...
      ]
    }
    ```

    Chaque entreprise du tableau inclut le profil enrichi complet, tous les signaux correspondants, et les contacts de personnes enrichis.
  </Tab>
</Tabs>

<Note>
  Les champs `body` personnalisés issus de `destination_config` apparaissent à la racine de la charge utile (par exemple, `"pipeline": "my-webhook"` s'il est configuré dans votre destination).
</Note>

***

## Signaux d'expansion

Aux côtés de `jobs`, `news` et `advertisements`, un monitor peut surveiller les **signaux d'expansion** — la preuve datée qu'une entreprise entre sur un nouveau marché ou s'y développe. Ajoutez `expansions` à `signal_types` :

```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"
  }
}
```

Les filtres d'expansion utilisent le vocabulaire de [Expansion Search](/fr/api-reference/endpoint/expansions/market_lookup), et non celui des offres d'emploi/actualités/publicités — `froms` et `tos` pour le corridor, plus `stages`, `scopes`, `momentum`, `freshness`, `signal_types`, `signal_subtypes`, `signal_strengths`, `source_types` et `window_days`. Résolvez les slugs valides depuis [Expansion Reference](/fr/api-reference/endpoint/expansions/types).

<Note>
  Les signaux d'expansion sont regroupés **par entreprise et par marché**, et non par signal. Une entreprise qui entre sur deux marchés produit deux entrées, chacune portant sa propre chronologie de signaux pour ce marché.
</Note>

### Charge utile des signaux d'expansion

```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": [...]
    }
  ]
}
```

La signification de chaque champ figure dans la [Référence des champs d'expansion](/fr/knowledge-base/concepts/expansion-field-reference). Pour récupérer les mêmes lignes à la demande plutôt que via un déclencheur, utilisez [Expansion Signal Search](/fr/api-reference/endpoint/expansions/signal_search).

***

## Destination e-mail

Pour les équipes qui préfèrent la livraison par e-mail, définissez `destination_type` sur `"email"` :

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

<Info>
  Pubrio prend en charge la livraison d'e-mails en marque blanche pour les agences et les équipes. [Contactez-nous](https://pubrio.com/en/get-in-touch) pour en savoir plus sur la personnalisation du domaine expéditeur et de l'image de marque.
</Info>

***

## Dépannage

<AccordionGroup>
  <Accordion title="Le webhook ne reçoit pas de charges utiles">
    * Vérifiez que votre point de terminaison est accessible publiquement (pas derrière un pare-feu ou un VPN)
    * Assurez-vous qu'il renvoie un code de statut `200` — les autres codes sont traités comme des échecs
    * Utilisez le point de terminaison [Validate Webhook](/fr/api-reference/endpoint/monitors/webhook_validate) pour tester la connectivité
    * Consultez les [Statistic Logs](/fr/api-reference/endpoint/monitors/statistics_logs) pour les messages d'erreur et les codes de réponse
  </Accordion>

  <Accordion title="Monitor mis en pause après des échecs">
    Si votre webhook renvoie systématiquement des codes non-200, le monitor se met en pause après avoir atteint `max_failure_trigger` échecs consécutifs. Corrigez le problème puis réactivez via [Update Monitor](/fr/api-reference/endpoint/monitors/update).
  </Accordion>

  <Accordion title="Charges utiles en double">
    Si une livraison échoue et que des tentatives sont configurées, vous pouvez recevoir plusieurs fois la même charge utile. Utilisez `triggered_at` ou l'identifiant de journal pour dédupliquer de votre côté.
  </Accordion>

  <Accordion title="Charge utile trop volumineuse">
    Réduisez `max_records_per_trigger` pour limiter le nombre d'enregistrements par livraison. Vous pouvez aussi restreindre vos filtres pour réduire le volume de signaux correspondants.
  </Accordion>
</AccordionGroup>
