> ## Documentation Index
> Fetch the complete documentation index at: https://docs.godiligent.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Register Webhook

> Register a webhook endpoint for your account.

## Endpoint

`POST /webhooks`

Creates a **new** webhook endpoint for the authenticated customer. You can register up to **10 webhooks**, each with its own URL, secret, and event filter. Event delivery fans out to every active webhook whose filter matches the event.

<Note>
  **Behavior change:** this endpoint previously upserted a single webhook per customer — repeated `POST`s updated the same record. It now **always creates a new webhook**. To modify an existing webhook, use [`PATCH /webhooks/{webhook_id}`](./update). To remove one, use [`DELETE /webhooks/{webhook_id}`](./delete).
</Note>

## Request Body

JSON object with the following fields:

| Field        | Type      | Required | Description                                                                                                                                |
| ------------ | --------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| webhook\_url | string    | Yes      | HTTPS URL to receive webhook events. Must start with `https://`.                                                                           |
| secret       | string    | No       | Secret used to sign webhook payloads (`X-Signature` header). Write-only — never returned by the API. Empty string is treated as no secret. |
| is\_active   | boolean   | No       | Whether the webhook is active. Defaults to `true`.                                                                                         |
| events       | string\[] | No       | List of event types to subscribe to. Defaults to an empty list (no events).                                                                |

### Supported Event Types

* `cdd_state_changed`: When the state of a CDD changes to either inconclusive or complete.
* `monitoring_alert_fired`: When a monitoring alert is fired on failure.
* `cdd_document_fetched`: When a new document is successfully added to a CDD case.
* `search_completed`: When a name screening search completes and results are available.
* `alert_remediated`: When a name screening alert has been remediated (all hits resolved).
* `flow_run_completed`: When a flow run finishes successfully (`COMPLETED`).
* `flow_run_failed`: When a flow run fails (`FAILED`).

### Example Request

```json theme={null}
{
  "webhook_url": "https://www.testing-webhooks.com",
  "is_active": true,
  "secret": "some-secret",
  "events": ["cdd_state_changed", "monitoring_alert_fired", "search_completed"]
}
```

## Responses

### 201 Created

The webhook was created. The response body is the created webhook (the `secret` is never echoed — `has_secret` indicates whether one is set).

```json theme={null}
{
  "id": "df89eb16-4c6a-439f-b668-7cca0cd786fa",
  "webhook_url": "https://www.testing-webhooks.com",
  "is_active": true,
  "has_secret": true,
  "status": "active",
  "last_delivery_at": null,
  "last_delivery_status": null,
  "events": ["cdd_state_changed", "monitoring_alert_fired", "search_completed"]
}
```

### 400 Bad Request

Input validation failed.

```json theme={null}
{
  "error": [
    {
      "code": "invalid_type",
      "expected": "string",
      "received": "number",
      "path": ["webhook_url"],
      "message": "Expected string, received number"
    }
  ]
}
```

### 409 Conflict

The customer already has the maximum of 10 webhooks. Delete one before creating another.

```json theme={null}
{
  "error": "Webhook limit reached (max 10 per customer)"
}
```

### 500 Internal Server Error

Unexpected error occurred.

```json theme={null}
{
  "error": "Internal server error"
}
```

## Authentication

This endpoint requires authentication. The webhook is associated with the authenticated customer.


## OpenAPI

````yaml POST /webhooks
openapi: 3.0.1
info:
  version: 1.5.0
  title: Diligent
  description: >
    Download Postman collection
    [here](https://docs.godiligent.ai/files/postman_collection.json).
servers:
  - url: https://api.godiligent.ai
    description: Production
  - url: https://api.sandbox.godiligent.ai
    description: Sandbox
security:
  - xApiKey: []
tags:
  - name: CDD
    description: Customer Due Diligence
  - name: Company
    description: Company Information
  - name: Blocked Companies
    description: Manage blocked companies
  - name: Monitorings
    description: Website monitoring and alerts for changes and risks
  - name: Webhooks
    description: >

      ## How to Secure Webhook Deliveries

      To ensure that webhook payloads are securely transmitted and verified.
      This guide explains how to configure and validate

      webhook deliveries using a shared secret.


      ### How It Works


      When setting up a webhook, a secret is configured on both the sender (our
      system) and the receiver (your endpoint). Each

      webhook payload is signed using this secret, allowing the receiver to
      verify its authenticity.


      #### Step 1: Configuring Your Webhook Secret


      1. When creating a webhook in our system, specify a unique secret key.
      This secret should be a strong, randomly

      generated string.

      2. Store this secret securely on your server; it should never be exposed
      publicly.


      #### Step 2: Receiving Webhook Payloads


      When your server receives a webhook event, the request will include an
      `X-Signature` header containing a HMAC signature

      of the payload.


      Example header:


      ```

      X-Signature: sha256=abcdef1234567890...

      ```


      #### Step 3: Validating the Webhook Signature


      To verify the webhook payload:


      1. Retrieve the `X-Signature` value from the request headers.

      2. Compute the HMAC SHA-256 signature of the request payload using your
      webhook secret.

      3. Compare the computed signature with the one in the `X-Signature`
      header.

      4. If they match, the webhook is valid.


      #### (Python)


      ```python

      import hashlib

      import hmac

      import json


      def verify_webhook_signature(secret, payload, signature):
        computed_signature = hmac.new(secret.encode(), payload.encode(), hashlib.sha256).hexdigest()
        expected_signature = f"sha256={computed_signature}"
        return hmac.compare_digest(expected_signature, signature)

      # Example usage:

      secret = "your_webhook_secret"

      payload = json.dumps({"event": "example"})

      received_signature = "sha256=abcdef1234567890..."


      if verify_webhook_signature(secret, payload, received_signature):
        print("Valid webhook received!")
      else:
        print("Invalid webhook signature!")
      ```


      #### (JavaScript)


      ```javascript

      const crypto = require('crypto');


      function verifyWebhookSignature (secret, payload, signature) {

      const computedSignature = `sha256=${crypto.createHmac('sha256', secret)

      .update(payload)

      .digest('hex')}`;

      return crypto.timingSafeEqual(Buffer.from(computedSignature),
      Buffer.from(signature));

      }


      // Example usage:

      const secret = "your_webhook_secret";

      const payload = JSON.stringify({ event: "example" });

      const receivedSignature = "sha256=abcdef1234567890...";


      if (verifyWebhookSignature(secret, payload, receivedSignature)) {

      console.log("Valid webhook received!");

      } else {

      console.log("Invalid webhook signature!");

      }

      ```


      #### Security Considerations


      - Always use HTTPS to prevent interception of webhook payloads.

      - Reject webhook requests that fail signature validation.

      - Rotate secrets periodically to enhance security.


      By following this guide, you ensure that webhook deliveries are secure and
      trusted.
  - name: Instant Screening (experimental)
    description: Instant Website Screening API
  - name: Name Screening
    description: Name screening search, alert management and remediation
paths:
  /webhooks:
    post:
      tags:
        - Webhooks
      summary: Register a webhook
      description: >-
        Creates a new webhook endpoint. A customer may register up to 10
        webhooks, each with its own URL, secret, and event filter. This endpoint
        always creates a new webhook — to modify an existing one use `PATCH
        /webhooks/{webhook_id}`.
      operationId: registerWebhook
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                webhook_url:
                  type: string
                  format: uri
                  description: Must be a valid URL starting with https.
                is_active:
                  type: boolean
                  default: true
                  description: Indicates if the webhook is active.
                secret:
                  type: string
                  description: >-
                    Secret used to sign the webhook payload, passed in the
                    `X-Signature` header. Write-only — it is never returned by
                    the API.
                events:
                  type: array
                  description: >-
                    List of events to trigger the webhook. If not provided, no
                    events will be triggered.
                  items:
                    type: string
                    enum:
                      - cdd_state_changed
                      - monitoring_alert_fired
                      - cdd_document_fetched
                      - search_completed
                      - alert_remediated
                      - flow_run_completed
                      - flow_run_failed
                    description: >-
                      __cdd_state_changed__: When the state of a CDD changes to
                      either inconclusive or complete.

                      __monitoring_alert_fired__: When a monitoring alert is
                      fired on failure.

                      __cdd_document_fetched__: When a new document is
                      successfully added to a CDD case.

                      __search_completed__: When a name screening search
                      completes and results are available.

                      __alert_remediated__: When a name screening alert has been
                      remediated.

                      __flow_run_completed__: When a flow run finishes
                      successfully (`COMPLETED`).

                      __flow_run_failed__: When a flow run fails (`FAILED`).
              required:
                - webhook_url
      responses:
        '201':
          description: Webhook created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Webhook'
        '400':
          description: Invalid input or validation error.
        '409':
          description: Webhook limit reached (maximum 10 per customer).
components:
  schemas:
    Webhook:
      type: object
      properties:
        id:
          type: string
          description: Unique ID for the webhook.
        webhook_url:
          type: string
          format: uri
        is_active:
          type: boolean
        has_secret:
          type: boolean
          description: >-
            Whether a signing secret is configured. The secret itself is never
            returned.
        status:
          type: string
          enum:
            - active
            - failing
            - disabled
          description: >-
            Derived health: `disabled` when inactive, `failing` when the last
            delivery returned a non-2xx status, otherwise `active`.
        last_delivery_at:
          type: string
          format: date-time
          nullable: true
          description: Timestamp of the most recent delivery attempt, or null if none.
        last_delivery_status:
          type: integer
          nullable: true
          description: >-
            HTTP status code of the most recent delivery attempt, or null if
            none.
        events:
          type: array
          items:
            type: string
            enum:
              - cdd_state_changed
              - monitoring_alert_fired
              - cdd_document_fetched
              - search_completed
              - alert_remediated
              - flow_run_completed
              - flow_run_failed
  securitySchemes:
    xApiKey:
      type: apiKey
      name: X-API-KEY
      in: header

````