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

# Webhooks API

> Manage webhooks for real-time event notifications

The Webhooks API allows you to create and manage webhooks that receive real-time notifications when escrow status changes, contracts are signed, cancellation requests are created, accepted, or rejected, a buyer rejects delivery, or identity verification status changes.

<Warning>
  You can create a maximum of 2 webhooks per developer account. Choose your
  endpoints carefully.
</Warning>

## Create Webhook

Create a new webhook endpoint to receive event notifications.

<Endpoint method="POST" path="/api/developer/webhooks" />

### Request Body

<ParamField body="url" type="string" required>
  Webhook URL (must be HTTPS in production)
</ParamField>

<ParamField body="events" type="array">
  Array of event types to subscribe to. Supported: `escrow.status.updated`,
  `contract.signed`, `escrow.cancellation.requested`,
  `escrow.cancellation.rejected`, `escrow.cancellation.accepted`,
  `escrow.updated`, `escrow.deposit_proof.rejected` (guest instant-escrow
  payment proof rejected by admin), `escrow.delivery.rejected` (buyer rejected
  delivery; includes optional reason), `identity.verification.updated`
  (pre-account KYC approved or rejected), `identity.verification.linked`
  (KYC attached when user registers on DHMAD). Default: `["escrow.status.updated"]`
</ParamField>

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://dhmad.tn/api/developer/webhooks \
    -H "Authorization: Bearer your_developer_token" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://example.com/webhooks/dhmad",
      "events": ["escrow.status.updated"]
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://dhmad.tn/api/developer/webhooks", {
    method: "POST",
    headers: {
      Authorization: "Bearer your_developer_token",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      url: "https://example.com/webhooks/dhmad",
      events: ["escrow.status.updated", "contract.signed"],
    }),
  });

  const data = await response.json();
  ```

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

  headers = {
      'Authorization': 'Bearer your_developer_token',
      'Content-Type': 'application/json'
  }

  data = {
      'url': 'https://example.com/webhooks/dhmad',
      'events': ['escrow.status.updated', 'contract.signed']
  }

  response = requests.post(
      'https://dhmad.tn/api/developer/webhooks',
      json=data,
      headers=headers
  )

  data = response.json()
  ```
</CodeGroup>

### Example Response

```json theme={null}
{
  "message": "Webhook created successfully",
  "webhook": {
    "id": "507f1f77bcf86cd799439011",
    "url": "https://example.com/webhooks/dhmad",
    "secret": "a1b2c3d4e5f6...your_webhook_secret_hex",
    "events": ["escrow.status.updated", "contract.signed"],
    "isActive": true,
    "createdAt": "2024-01-15T10:00:00Z"
  }
}
```

<Warning>
  The `secret` field is **only returned when creating a webhook** and when regenerating the secret. It is never included in list or get responses. Copy and store it immediately.
</Warning>

## List Webhooks

Get all webhooks for your developer account.

<Endpoint method="GET" path="/api/developer/webhooks" />

### Example Request

```bash theme={null}
curl -X GET https://dhmad.tn/api/developer/webhooks \
  -H "Authorization: Bearer your_developer_token"
```

### Example Response

```json theme={null}
{
  "webhooks": [
    {
      "id": "507f1f77bcf86cd799439011",
      "url": "https://example.com/webhooks/dhmad",
      "events": ["escrow.status.updated", "contract.signed"],
      "isActive": true,
      "lastTriggeredAt": "2024-01-15T10:30:00Z",
      "lastResponseStatus": 200,
      "failureCount": 0,
      "createdAt": "2024-01-15T10:00:00Z",
      "updatedAt": "2024-01-15T10:00:00Z"
    }
  ]
}
```

## Get Webhook

Get details of a specific webhook.

<Endpoint method="GET" path="/api/developer/webhooks/:id" />

### Path Parameters

<ParamField path="id" type="string" required>
  The webhook ID
</ParamField>

### Example Request

```bash theme={null}
curl -X GET https://dhmad.tn/api/developer/webhooks/507f1f77bcf86cd799439011 \
  -H "Authorization: Bearer your_developer_token"
```

## Update Webhook

Update a webhook's URL, events, or active status.

<Endpoint method="PUT" path="/api/developer/webhooks/:id" />

### Path Parameters

<ParamField path="id" type="string" required>
  The webhook ID
</ParamField>

### Request Body

<ParamField body="url" type="string">
  New webhook URL (optional)
</ParamField>

<ParamField body="events" type="array">
  New array of event types (optional)
</ParamField>

<ParamField body="isActive" type="boolean">
  Whether the webhook is active (optional)
</ParamField>

### Example Request

```bash theme={null}
curl -X PUT https://dhmad.tn/api/developer/webhooks/507f1f77bcf86cd799439011 \
  -H "Authorization: Bearer your_developer_token" \
  -H "Content-Type: application/json" \
  -d '{
    "isActive": false
  }'
```

## Regenerate Secret

Generate a new signing secret for a webhook. The old secret will immediately stop working.

<Endpoint method="POST" path="/api/developer/webhooks/:id/regenerate-secret" />

### Path Parameters

<ParamField path="id" type="string" required>
  The webhook ID
</ParamField>

### Example Request

```bash theme={null}
curl -X POST https://dhmad.tn/api/developer/webhooks/507f1f77bcf86cd799439011/regenerate-secret \
  -H "Authorization: Bearer your_developer_token"
```

### Example Response

```json theme={null}
{
  "message": "Webhook secret regenerated successfully",
  "secret": "e7f8a9b0c1d2...new_webhook_secret_hex"
}
```

<Warning>
  The new secret is only shown in this response. Copy and store it immediately, then update your webhook handler to use the new secret for signature verification.
</Warning>

## Delete Webhook

Delete a webhook permanently.

<Endpoint method="DELETE" path="/api/developer/webhooks/:id" />

### Path Parameters

<ParamField path="id" type="string" required>
  The webhook ID
</ParamField>

### Example Request

```bash theme={null}
curl -X DELETE https://dhmad.tn/api/developer/webhooks/507f1f77bcf86cd799439011 \
  -H "Authorization: Bearer your_developer_token"
```

### Example Response

```json theme={null}
{
  "message": "Webhook deleted successfully"
}
```

## Response Fields

<ParamField response="webhook.id" type="string">
  Unique identifier for the webhook
</ParamField>

<ParamField response="webhook.url" type="string">
  Webhook endpoint URL
</ParamField>

<ParamField response="webhook.events" type="array">
  Array of subscribed event types (e.g. "escrow\.status.updated",
  "contract.signed", "escrow\.cancellation.requested",
  "escrow\.cancellation.rejected", "escrow\.cancellation.accepted",
  "escrow\.delivery.rejected")
</ParamField>

<ParamField response="webhook.isActive" type="boolean">
  Whether the webhook is currently active
</ParamField>

<ParamField response="webhook.lastTriggeredAt" type="string">
  ISO 8601 timestamp of the last webhook delivery
</ParamField>

<ParamField response="webhook.lastResponseStatus" type="number">
  HTTP status code from the last webhook delivery attempt
</ParamField>

<ParamField response="webhook.failureCount" type="number">
  Number of consecutive delivery failures
</ParamField>

## Error Responses

### 400 Bad Request

**Webhook Limit Reached**

```json theme={null}
{
  "error": "Maximum 2 webhooks allowed per developer"
}
```

**Invalid URL**

```json theme={null}
{
  "error": "Invalid URL format"
}
```

**HTTPS Required (Production)**

```json theme={null}
{
  "error": "Only HTTPS URLs are allowed in production"
}
```

### 401 Unauthorized

```json theme={null}
{
  "error": "Unauthorized",
  "message": "Invalid or missing developer token"
}
```

### 404 Not Found

```json theme={null}
{
  "error": "Webhook not found"
}
```

***

<Info>
  For detailed information about webhook events, payloads, and signature
  verification, see the [Webhooks Guide](/guides/webhooks).
</Info>
