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

# Webhook Endpoints API — register event destinations

> Register URLs to receive real-time event notifications, manage endpoint settings, rotate signing secrets, test delivery, and view delivery logs.

Webhook endpoints are the URLs on your server that Dubu sends event notifications to. When something significant happens in your account — a deposit settles, a customer completes KYC, or a checkout payment is received — Dubu POSTs a signed JSON payload to every active endpoint subscribed to that event type. This page covers how to register and manage your endpoints. For the full list of event types and their payloads, see [Webhook event types and payload reference](/api-reference/webhooks/events).

All routes require authentication via API key or JWT bearer token.

## Endpoint object

<ResponseField name="id" type="string">
  Unique endpoint identifier (UUID).
</ResponseField>

<ResponseField name="url" type="string">
  The HTTPS URL Dubu delivers events to.
</ResponseField>

<ResponseField name="events" type="array">
  List of event type strings this endpoint is subscribed to. An empty array means all events are delivered.
</ResponseField>

<ResponseField name="is_active" type="boolean">
  Whether this endpoint is currently receiving events.
</ResponseField>

<ResponseField name="created_at" type="string">
  ISO 8601 creation timestamp.
</ResponseField>

<ResponseField name="updated_at" type="string">
  ISO 8601 last-updated timestamp.
</ResponseField>

***

## Register an endpoint

```
POST /webhooks/endpoints
```

Register a new URL to receive webhook events. Dubu returns the endpoint's signing secret (`secret`) in this response — store it securely. It is only shown once and is used to verify that incoming requests genuinely originate from Dubu. See [verifying signatures](/api-reference/webhooks/events#verifying-signatures) for how to use it.

### Request body

<ParamField body="url" type="string" required>
  The fully-qualified HTTPS URL Dubu should POST events to. Must be a valid URL.
</ParamField>

<ParamField body="events" type="array" required>
  Array of event type strings to subscribe to (e.g. `["deposit.settled", "checkout.payment.completed"]`). Pass an empty array `[]` to subscribe to all events.
</ParamField>

### Example

```bash theme={null}
curl -X POST https://api.dubupay.com/api/v1/webhooks/endpoints \
  -H "X-Api-Key: dubu_sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourserver.com/webhooks/dubu",
    "events": ["deposit.settled", "deposit.failed", "checkout.payment.completed"]
  }'
```

### Response

Returns `201 Created`. The `secret` field is only present in this response.

```json theme={null}
{
  "success": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "url": "https://yourserver.com/webhooks/dubu",
    "events": ["deposit.settled", "deposit.failed", "checkout.payment.completed"],
    "is_active": true,
    "created_at": "2024-01-15T10:00:00.000Z",
    "secret": "whsec_Abc123XYZ..."
  }
}
```

***

## List endpoints

```
GET /webhooks/endpoints
```

Returns all registered webhook endpoints for your account. The `secret` field is never returned in list or get responses — rotate the secret if you need to retrieve it again.

### Example

```bash theme={null}
curl https://api.dubupay.com/api/v1/webhooks/endpoints \
  -H "X-Api-Key: dubu_sk_live_YOUR_API_KEY"
```

***

## Update an endpoint

```
PATCH /webhooks/endpoints/:id
```

Update the URL, subscribed events, or active status of an endpoint.

<ParamField path="id" type="string" required>
  UUID of the endpoint to update.
</ParamField>

<ParamField body="url" type="string">
  New delivery URL.
</ParamField>

<ParamField body="events" type="array">
  Updated list of event type strings. Replaces the current subscription list.
</ParamField>

<ParamField body="is_active" type="boolean">
  Set to `false` to pause delivery without deleting the endpoint.
</ParamField>

### Example

```bash theme={null}
curl -X PATCH https://api.dubupay.com/api/v1/webhooks/endpoints/endpoint_uuid_here \
  -H "X-Api-Key: dubu_sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"is_active": false}'
```

***

## Delete an endpoint

```
DELETE /webhooks/endpoints/:id
```

Permanently removes a webhook endpoint. Dubu will stop delivering events to this URL immediately.

<ParamField path="id" type="string" required>
  UUID of the endpoint to delete.
</ParamField>

```bash theme={null}
curl -X DELETE https://api.dubupay.com/api/v1/webhooks/endpoints/endpoint_uuid_here \
  -H "X-Api-Key: dubu_sk_live_YOUR_API_KEY"
```

***

## Send a test event

```
POST /webhooks/endpoints/:id/test
```

Triggers an immediate test delivery to the endpoint. Dubu sends a signed payload to your URL so you can verify that your server receives and processes events correctly without waiting for a real event.

<ParamField path="id" type="string" required>
  UUID of the endpoint to test.
</ParamField>

```bash theme={null}
curl -X POST https://api.dubupay.com/api/v1/webhooks/endpoints/endpoint_uuid_here/test \
  -H "X-Api-Key: dubu_sk_live_YOUR_API_KEY"
```

The response includes the payload that was sent and whether the delivery succeeded.

```json theme={null}
{
  "success": true,
  "data": {
    "success": true,
    "status": 200,
    "payload": {
      "event": "test.webhook",
      "data": {
        "message": "This is a test webhook from Dubu API.",
        "endpoint_id": "endpoint_uuid_here",
        "timestamp": "2024-01-15T10:00:00.000Z"
      },
      "timestamp": "2024-01-15T10:00:00.000Z",
      "_test": true
    }
  }
}
```

***

## Rotate signing secret

```
POST /webhooks/endpoints/:id/rotate-secret
```

Generates a new signing secret for an endpoint. After rotating, you must update your server to use the new secret for signature verification. The previous secret stops working immediately.

<ParamField path="id" type="string" required>
  UUID of the endpoint whose secret you want to rotate.
</ParamField>

```bash theme={null}
curl -X POST https://api.dubupay.com/api/v1/webhooks/endpoints/endpoint_uuid_here/rotate-secret \
  -H "X-Api-Key: dubu_sk_live_YOUR_API_KEY"
```

```json theme={null}
{
  "success": true,
  "data": {
    "id": "endpoint_uuid_here",
    "secret": "whsec_NewSecret123..."
  }
}
```

***

## View delivery logs

```
GET /webhooks/logs
```

Returns a paginated log of all webhook delivery attempts for your account, including the payload sent, the HTTP status code returned by your server, and whether delivery was considered successful.

### Query parameters

<ParamField query="endpoint_id" type="string">
  Filter logs to a specific endpoint.
</ParamField>

<ParamField query="event" type="string">
  Filter by event type, e.g. `deposit.settled`.
</ParamField>

<ParamField query="success" type="string">
  `true` to see only successful deliveries, `false` to see only failed ones.
</ParamField>

<ParamField query="page" type="number">
  Page number (1-indexed).
</ParamField>

<ParamField query="limit" type="number">
  Results per page. Maximum `100`. Defaults to `50`.
</ParamField>

### Example

```bash theme={null}
curl "https://api.dubupay.com/api/v1/webhooks/logs?success=false&limit=20" \
  -H "X-Api-Key: dubu_sk_live_YOUR_API_KEY"
```

### Log entry fields

<ResponseField name="id" type="string">
  Log entry UUID.
</ResponseField>

<ResponseField name="endpoint_id" type="string">
  UUID of the endpoint this delivery was attempted to.
</ResponseField>

<ResponseField name="endpoint_url" type="string">
  URL of the endpoint at the time of delivery.
</ResponseField>

<ResponseField name="event" type="string">
  The event type that was delivered.
</ResponseField>

<ResponseField name="payload" type="object">
  The full JSON payload that was sent to your endpoint.
</ResponseField>

<ResponseField name="status_code" type="number">
  HTTP status code returned by your server. `0` if the connection failed.
</ResponseField>

<ResponseField name="success" type="boolean">
  `true` if your server responded with a 2xx status code.
</ResponseField>

<ResponseField name="error" type="string">
  Error description if delivery failed. `null` on success.
</ResponseField>

<ResponseField name="created_at" type="string">
  ISO 8601 timestamp of the delivery attempt.
</ResponseField>
