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

# Register Webhook

> Register a URL to receive real-time event notifications from DialNexa.

<Warning>
  **Legacy endpoint - deprecated.** Unversioned endpoints are scheduled for removal on **July 31, 2026**. Use the [`/v1` version](/docs/api-reference/v1/webhooks/create) for new integrations. This endpoint remains available for existing integrations until then.
</Warning>

Registers a URL endpoint to receive event notifications. When subscribed events occur, such as a call completing or a campaign finishing, DialNexa sends an HTTP `POST` to your URL with a signed JSON payload.

## How webhook verification works

Every request DialNexa sends to your endpoint includes an `x-dialnexa-signature` header. This is an HMAC-SHA256 signature of the raw request body as a bare hex digest (no prefix), generated using the `secret` you provide when registering the webhook. Verify this signature on your server to confirm the request is genuinely from DialNexa and hasn't been tampered with.

```python theme={null}
import hmac, hashlib

def verify_signature(payload_body: bytes, secret: str, signature_header: str) -> bool:
    expected = hmac.new(secret.encode(), payload_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature_header)
```

## Available events

| Event                     | Triggered when                            |
| ------------------------- | ----------------------------------------- |
| `call.completed`          | A call ends successfully.                 |
| `call.failed`             | A call attempt fails.                     |
| `call.no_answer`          | No one picks up within the ring timeout.  |
| `campaign.completed`      | All leads in a campaign have been called. |
| `campaign.paused`         | A campaign is paused.                     |
| `workflow.lead.completed` | A lead finishes all steps in a workflow.  |


## OpenAPI

````yaml POST /user-webhooks
openapi: 3.0.0
info:
  title: DialNexa API
  description: >-
    Public REST API for the DialNexa voice AI platform. Versioned endpoints are
    under /v1; unversioned endpoints are legacy and deprecated.
  version: 1.0.0
servers:
  - url: https://api.dialnexa.com
    description: DialNexa production API
security:
  - bearer: []
tags:
  - name: API Keys
  - name: Agent Functions
  - name: Agents V1
  - name: Agents2
  - name: Batch Calls
  - name: Batch Calls V1
  - name: Call Logs
  - name: Calls
  - name: Calls V1
  - name: Campaign Leads
  - name: Campaigns
  - name: External Webhooks
  - name: Knowledge Base
  - name: Knowledge Base V1
  - name: LLMs
  - name: LLMs V1
  - name: Languages
  - name: Languages V1
  - name: Organization Phone Numbers
  - name: Organization Phone Numbers V1
  - name: Phone Number Pricing
  - name: Phone Number Pricing V1
  - name: Transcribers
  - name: Transcribers V1
  - name: User Webhooks
  - name: User Webhooks V1
  - name: V1
  - name: Voices
  - name: Voices V1
  - name: Webcall
  - name: Workflow Leads
  - name: Workflow Leads V1
  - name: Workflows
  - name: Workflows V1
paths:
  /user-webhooks:
    post:
      tags:
        - User Webhooks
      summary: Create a new user webhook
      description: >-
        **Legacy endpoint - deprecated, scheduled for removal on July 31,
        2026.** Use the `/v1` version for new integrations. 
      operationId: UserWebhooksController_create
      parameters:
        - name: x-organization-id
          in: header
          description: RSA encrypted organization ID (base64 format)
          required: true
          schema:
            type: string
            example: BASE64_ENCRYPTED_ORG_ID_HERE
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateUserWebhookDto'
      responses:
        '201':
          description: ''
      deprecated: true
components:
  schemas:
    CreateUserWebhookDto:
      type: object
      properties:
        url:
          type: string
          example: https://webhook.site/your-endpoint
          description: The URL to which webhook events will be sent.
        events:
          example:
            - order.paid
            - order.failed
          description: List of events this webhook is subscribed to.
          type: array
          items:
            type: string
        is_active:
          type: boolean
          example: true
          description: Whether the webhook is active.
        secret:
          type: string
          example: mySuperSecret
          description: Secret used to sign webhook payloads.
      required:
        - url
        - events
        - secret
  securitySchemes:
    bearer:
      scheme: bearer
      bearerFormat: JWT
      type: http

````