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

# Webhook 설정

> Webhook 전달 대상을 구성하고, 엔드포인트를 검증하며, 서명을 확인하고, 페이로드를 처리하세요.

Webhook은 모니터 결과를 수신하는 권장 방법입니다. 모니터가 트리거되면, Pubrio가 구성된 URL로 JSON 페이로드를 포함한 POST 요청을 실시간으로 전송합니다.

## 사전 요구 사항

* 모니터 접근 권한이 있는 Pubrio API 키
* 공개적으로 접근 가능한 HTTPS 엔드포인트(또는 [usewebhook.com](https://usewebhook.com)의 테스트 URL)

<Tip>
  **빠른 테스트:** [usewebhook.com](https://usewebhook.com)을 사용하여 무료 임시 webhook URL을 생성하세요. 아무것도 배포하지 않고 모든 수신 페이로드를 확인할 수 있습니다.
</Tip>

***

## 1단계: 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>

**응답:**

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

`headers` 객체는 매 전달마다 커스텀 HTTP 헤더를 추가합니다(인증에 유용). `body` 객체는 webhook 페이로드의 루트 레벨에 커스텀 필드를 추가합니다.

<Tip>
  응답의 `signature`를 저장하세요 — 수신 페이로드를 검증하는 데 필요합니다. 이것은 생성 시와 [서명 공개](/ko/api-reference/endpoint/monitors/signature_reveal) 엔드포인트를 통해서만 반환됩니다.
</Tip>

***

## 2단계: Webhook 연결 검증

[Webhook 검증](/ko/api-reference/endpoint/monitors/webhook_validate) 엔드포인트를 사용하여 엔드포인트가 도달 가능한지 테스트합니다. 이것은 플레이스홀더 데이터가 포함된 **샘플 페이로드**를 전송합니다 — 크레딧이 소비되지 않고, 실제 신호도 가져오지 않습니다.

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

성공적인 응답은 전송된 샘플 요청 페이로드와 엔드포인트가 반환한 응답을 포함합니다 — 이를 통해 라이브 전환 전에 연결이 정상임을 확인할 수 있습니다.

***

## 3단계: 실제 데이터로 테스트

연결이 검증되면, [프로세스 트라이](/ko/api-reference/endpoint/monitors/process_try) 엔드포인트를 사용하여 실제 실행을 트리거합니다. 이것은 실제 신호를 가져와 webhook으로 전달합니다 — `tried_at`에 최근 과거 날짜를 사용하여 데이터가 있는지 확인하세요:

<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>
  validate와 달리, try 엔드포인트는 실제 스캔을 실행하고 **크레딧을 소비합니다**. 실제 페이로드가 올바르게 도착하는지 확인하고, 예약된 스캔이 시작되기 전에 결과를 빠르게 추정하는 데 사용하세요.
</Info>

***

## 4단계: 서명 검증

각 모니터에는 수신 페이로드가 Pubrio에서 온 것인지 확인하기 위한 고유 서명이 있습니다.

<CodeGroup>
  ```bash cURL — 서명 공개 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"
  }
}
```

이 서명을 수신 페이로드의 `monitor.monitor_id`와 비교하여 진위를 검증합니다.

***

## Webhook 페이로드 구조

페이로드는 모니터의 `detection_mode`에 따라 다릅니다:

<Tabs>
  <Tab title="신호 우선">
    `signal_first` 모드에서는 페이로드에 최상위 `signals` 배열이 포함됩니다:

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

    각 신호 항목에는 신호 세부 정보와 관련된 보강 기업 및 인물이 포함됩니다.
  </Tab>

  <Tab title="기업 우선">
    `company_first` 모드에서는 페이로드에 보강된 기업 데이터와 중첩된 신호가 포함된 최상위 `companies` 배열이 있습니다:

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

    배열의 각 기업에는 전체 보강 프로필, 모든 매칭 신호, 보강된 인물 연락처가 포함됩니다.
  </Tab>
</Tabs>

<Note>
  `destination_config`의 커스텀 `body` 필드는 페이로드의 루트 레벨에 병합됩니다. 이를 사용하여 내부 라우팅 또는 태깅을 위한 정적 메타데이터를 추가하세요(예: `"pipeline": "my-webhook"`).
</Note>

***

## 이메일 전달 대상

이메일 전달을 선호하는 팀은 `destination_type`을 `"email"`로 설정하세요:

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

<Info>
  Pubrio는 에이전시와 팀을 위한 화이트 라벨 이메일 전달을 지원합니다. 발신자 도메인 및 브랜딩 커스터마이징에 대해 [문의하기](https://pubrio.com/en/get-in-touch)에서 알아보세요.
</Info>

***

## 문제 해결

<AccordionGroup>
  <Accordion title="Webhook이 페이로드를 수신하지 않음">
    * 엔드포인트가 공개적으로 접근 가능한지 확인하세요(방화벽이나 VPN 뒤에 있지 않은지)
    * `200` 상태 코드를 반환하는지 확인하세요 — 다른 코드는 실패로 처리됩니다
    * [Webhook 검증](/ko/api-reference/endpoint/monitors/webhook_validate) 엔드포인트를 사용하여 연결을 테스트하세요
    * [통계 로그](/ko/api-reference/endpoint/monitors/statistics_logs)에서 오류 메시지와 응답 코드를 확인하세요
  </Accordion>

  <Accordion title="실패 후 모니터 일시 중지">
    webhook이 지속적으로 200이 아닌 코드를 반환하면, `max_failure_trigger` 연속 실패 횟수에 도달한 후 모니터가 일시 중지됩니다. 문제를 수정하고 [모니터 업데이트](/ko/api-reference/endpoint/monitors/update)를 통해 다시 활성화하세요.
  </Accordion>

  <Accordion title="중복 페이로드">
    전달이 실패하고 재시도가 구성된 경우, 동일한 페이로드를 여러 번 수신할 수 있습니다. `triggered_at` 또는 로그 ID를 사용하여 중복을 제거하세요.
  </Accordion>

  <Accordion title="페이로드가 너무 큼">
    `max_records_per_trigger`를 줄여 전달당 레코드 수를 제한하세요. 필터를 좁혀 매칭되는 신호 볼륨을 줄일 수도 있습니다.
  </Accordion>
</AccordionGroup>
