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

# Create Webhook

> Register webhook endpoints for receiving real-time event notifications from your Devdraft application

The Create Webhook endpoint enables you to register webhook endpoints for receiving real-time event notifications from your Devdraft application. Webhooks allow your application to receive automated notifications when specific events occur, enabling real-time integration and workflow automation.

## Endpoint Details

* **URL**: `/api/v0/webhooks`
* **Method**: `POST`
* **Authentication**: Required (API Key Authentication with Scopes)
* **Content-Type**: `application/json`
* **Required Scope**: `webhook:create`

## Authentication

This endpoint requires API key authentication with specific scopes:

### Required Headers

```json theme={null}
x-client-key: your-client-key
x-client-secret: your-client-secret
```

### Required Scope

Your API key must have the `webhook:create` scope to access this endpoint.

## Request Body

### Required Fields

| Field | Type   | Description                            | Validation       |
| ----- | ------ | -------------------------------------- | ---------------- |
| name  | string | Webhook name for identification        | 3-100 characters |
| url   | string | Endpoint URL where events will be sent | Valid URL format |

### Optional Fields

| Field           | Type    | Description                               | Default        | Validation                       |
| --------------- | ------- | ----------------------------------------- | -------------- | -------------------------------- |
| isActive        | boolean | Whether webhook is active                 | true           | Boolean                          |
| signing\_secret | string  | Secret for payload signature verification | Auto-generated | Min 32 chars, alphanumeric + \_- |
| encrypted       | boolean | Whether payloads should be encrypted      | false          | Boolean                          |

### Request Schema

<CodeGroup>
  ```json Request Schema theme={null}
  {
    "name": "string",
    "url": "string",
    "isActive": "boolean",
    "signing_secret": "string",
    "encrypted": "boolean"
  }
  ```
</CodeGroup>

## Response

### Success Response (201 Created)

<CodeGroup>
  ```json Response theme={null}
  {
    "id": "wh_123456789",
    "name": "Payment Notifications",
    "url": "https://api.example.com/webhooks/payments",
    "isActive": true,
    "encrypted": false,
    "created_at": "2024-03-20T12:00:00.000Z",
    "updated_at": "2024-03-20T12:00:00.000Z",
    "delivery_stats": {
      "total_events": 0,
      "successful_deliveries": 0,
      "failed_deliveries": 0,
      "last_delivery": null
    }
  }
  ```
</CodeGroup>

### Error Responses

<CodeGroup>
  ```json 400 Bad Request - Invalid Input theme={null}
  {
    "statusCode": 400,
    "message": "Invalid webhook URL format",
    "error": "Bad Request",
    "details": "URL must be a valid HTTPS endpoint"
  }
  ```

  ```json 400 Bad Request - Validation Errors theme={null}
  {
    "statusCode": 400,
    "message": [
      "Name must be at least 3 characters long",
      "URL must be a valid URL",
      "Signing secret must be at least 32 characters and contain only letters, numbers, underscores, and hyphens"
    ],
    "error": "Bad Request"
  }
  ```

  ```json 401 Unauthorized - Missing Credentials theme={null}
  {
    "statusCode": 401,
    "message": "Client key or secret missing",
    "error": "Unauthorized",
    "details": "Please provide both x-client-key and x-client-secret headers"
  }
  ```

  ```json 403 Forbidden - Missing Scope theme={null}
  {
    "statusCode": 403,
    "message": "Missing required scope",
    "error": "Forbidden",
    "details": "API key does not have the required webhook:create scope"
  }
  ```
</CodeGroup>

## Field Validation Rules

<AccordionGroup>
  <Accordion title="Name Validation" icon="tag">
    * **Required**: Yes
    * **Type**: String
    * **Length**: 3-100 characters
    * **Description**: Human-readable name for webhook identification
  </Accordion>

  <Accordion title="URL Validation" icon="link">
    * **Required**: Yes
    * **Type**: String (URL format)
    * **Protocol**: Must be a valid URL (HTTPS recommended for production)
    * **Description**: Endpoint where webhook events will be sent
  </Accordion>

  <Accordion title="Signing Secret Validation" icon="key">
    * **Required**: No (auto-generated if not provided)
    * **Type**: String
    * **Pattern**: `^[a-zA-Z0-9_\-]{32,}$`
    * **Length**: Minimum 32 characters
    * **Characters**: Letters, numbers, underscores, and hyphens only
  </Accordion>

  <Accordion title="Active Status" icon="toggle-on">
    * **Required**: No
    * **Type**: Boolean
    * **Default**: `true`
    * **Description**: Whether webhook will receive events
  </Accordion>

  <Accordion title="Encryption" icon="lock">
    * **Required**: No
    * **Type**: Boolean
    * **Default**: `false`
    * **Description**: Whether webhook payloads should be encrypted
  </Accordion>
</AccordionGroup>

## Example Requests

<CodeGroup>
  ```bash Basic Webhook Creation theme={null}
  curl -X POST https://api.devdraft.ai/api/v0/webhooks \
    -H "Content-Type: application/json" \
    -H "x-client-key: your-client-key" \
    -H "x-client-secret: your-client-secret" \
    -d '{
      "name": "Payment Notifications",
      "url": "https://api.example.com/webhooks/payments"
    }'
  ```

  ```bash Webhook with Custom Configuration theme={null}
  curl -X POST https://api.devdraft.ai/api/v0/webhooks \
    -H "Content-Type: application/json" \
    -H "x-client-key: your-client-key" \
    -H "x-client-secret: your-client-secret" \
    -d '{
      "name": "Order Updates",
      "url": "https://api.example.com/webhooks/orders",
      "isActive": true,
      "signing_secret": "whsec_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
      "encrypted": true
    }'
  ```

  ```bash Inactive Webhook for Testing theme={null}
  curl -X POST https://api.devdraft.ai/api/v0/webhooks \
    -H "Content-Type: application/json" \
    -H "x-client-key: your-client-key" \
    -H "x-client-secret: your-client-secret" \
    -d '{
      "name": "Test Webhook",
      "url": "https://webhook.site/unique-url",
      "isActive": false
    }'
  ```

  ```javascript JavaScript/Node.js theme={null}
  const createWebhook = async (webhookData) => {
    try {
      const response = await fetch('https://api.devdraft.ai/api/v0/webhooks', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-client-key': process.env.DEVDRAFT_CLIENT_KEY,
          'x-client-secret': process.env.DEVDRAFT_CLIENT_SECRET
        },
        body: JSON.stringify(webhookData)
      });

      if (!response.ok) {
        throw new Error(`Webhook creation failed: ${response.statusText}`);
      }

      const webhook = await response.json();
      console.log('Webhook created:', webhook.id);
      
      return webhook;
    } catch (error) {
      console.error('Error creating webhook:', error);
      throw error;
    }
  }

  // Usage
  const webhook = await createWebhook({
    name: 'Payment Events',
    url: 'https://api.example.com/webhooks/payments',
    isActive: true,
    encrypted: false
  });
  ```

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

  class WebhookManager:
      def __init__(self, client_key, client_secret, base_url='https://api.devdraft.ai'):
          self.client_key = client_key
          self.client_secret = client_secret
          self.base_url = base_url
          
      def create_webhook(self, name, url, active=True, encrypted=False):
          headers = {
              'Content-Type': 'application/json',
              'x-client-key': self.client_key,
              'x-client-secret': self.client_secret
          }
          
          data = {
              'name': name,
              'url': url,
              'isActive': active,
              'encrypted': encrypted
          }
          
          response = requests.post(
              f"{self.base_url}/api/v0/webhooks",
              headers=headers,
              json=data
          )
          
          response.raise_for_status()
          return response.json()

  # Usage
  webhook_manager = WebhookManager(
      client_key=os.getenv('DEVDRAFT_CLIENT_KEY'),
      client_secret=os.getenv('DEVDRAFT_CLIENT_SECRET')
  )

  webhook = webhook_manager.create_webhook(
      name='Payment Events',
      url='https://api.example.com/webhooks/payments',
      active=True,
      encrypted=False
  )

  print(f"Created webhook: {webhook['id']}")
  ```
</CodeGroup>

## Use Cases

<CardGroup cols={2}>
  <Card title="Payment Event Notifications" icon="credit-card">
    Receive real-time updates about payment status changes
  </Card>

  <Card title="Invoice Lifecycle Tracking" icon="file-invoice">
    Monitor invoice creation, updates, and payments
  </Card>

  <Card title="Customer Activity Monitoring" icon="users">
    Track customer registration and profile updates
  </Card>

  <Card title="Transaction Processing" icon="exchange">
    Monitor transaction status and settlement events
  </Card>

  <Card title="Balance Updates" icon="wallet">
    Get notified when wallet balances change
  </Card>

  <Card title="Transfer Notifications" icon="arrow-right-arrow-left">
    Track the status of cross-chain transfers
  </Card>
</CardGroup>

## Integration Examples

### Express.js Webhook Handler

<CodeGroup>
  ```javascript Express.js Example theme={null}
  const express = require('express');
  const crypto = require('crypto');
  const app = express();

  // Middleware to capture raw body for signature verification
  app.use('/webhooks', express.raw({type: 'application/json'}));

  // Webhook endpoint to receive events
  app.post('/webhooks/payments', (req, res) => {
    const signature = req.headers['x-webhook-signature'];
    const payload = req.body;
    
    // Verify signature
    if (verifySignature(payload, signature, process.env.WEBHOOK_SECRET)) {
      const event = JSON.parse(payload);
      console.log('Received webhook event:', event.type);
      
      // Process the event
      handlePaymentEvent(event);
      
      res.status(200).send('OK');
    } else {
      res.status(401).send('Invalid signature');
    }
  });

  function verifySignature(payload, signature, secret) {
    const expectedSignature = crypto
      .createHmac('sha256', secret)
      .update(payload)
      .digest('hex');
      
    return crypto.timingSafeEqual(
      Buffer.from(signature),
      Buffer.from(`sha256=${expectedSignature}`)
    );
  }

  function handlePaymentEvent(event) {
    switch(event.type) {
      case 'payment.completed':
        console.log('Payment completed:', event.data.id);
        break;
      case 'payment.failed':
        console.log('Payment failed:', event.data.id);
        break;
      default:
        console.log('Unknown event type:', event.type);
    }
  }
  ```
</CodeGroup>

### Flask Webhook Handler

<CodeGroup>
  ```python Flask Example theme={null}
  from flask import Flask, request, jsonify
  import hmac
  import hashlib
  import json

  app = Flask(__name__)

  @app.route('/webhooks/payments', methods=['POST'])
  def handle_payment_webhook():
      signature = request.headers.get('x-webhook-signature')
      payload = request.get_data()
      
      # Verify signature
      if verify_signature(payload, signature, 'your-signing-secret'):
          event = request.get_json()
          print(f"Received event: {event['type']}")
          
          # Process the event
          process_payment_event(event)
          
          return 'OK', 200
      else:
          return 'Invalid signature', 401

  def verify_signature(payload, signature, secret):
      """Verify webhook signature"""
      expected_signature = hmac.new(
          secret.encode('utf-8'),
          payload,
          hashlib.sha256
      ).hexdigest()
      
      return hmac.compare_digest(signature, f"sha256={expected_signature}")

  def process_payment_event(event):
      if event['type'] == 'payment.completed':
          print(f"Payment completed: {event['data']['id']}")
      elif event['type'] == 'payment.failed':
          print(f"Payment failed: {event['data']['id']}")
      else:
          print(f"Unknown event type: {event['type']}")

  if __name__ == '__main__':
      app.run(debug=True)
  ```
</CodeGroup>

## Security Features

<AccordionGroup>
  <Accordion title="Signature Verification" icon="shield-check">
    * **HMAC SHA-256**: Cryptographic signature for payload verification
    * **Timing-safe comparison**: Prevent timing attacks
    * **Automatic generation**: Secure secrets generated automatically
  </Accordion>

  <Accordion title="Payload Encryption" icon="lock">
    * **AES-256 encryption**: Industry-standard encryption for sensitive data
    * **Key rotation**: Support for periodic key rotation
    * **Selective encryption**: Choose which webhooks need encryption
  </Accordion>

  <Accordion title="Access Control" icon="key">
    * **Scope-based permissions**: `webhook:create` scope required
    * **Application isolation**: Webhooks isolated by application
    * **Rate limiting**: Protection against abuse
  </Accordion>
</AccordionGroup>

## Best Practices

<Steps>
  <Step title="Use HTTPS Endpoints">
    Always use HTTPS URLs for webhook endpoints in production to ensure data security.
  </Step>

  <Step title="Verify Signatures">
    Always verify webhook signatures before processing events to ensure authenticity.
  </Step>

  <Step title="Handle Retries">
    Implement proper error handling and return appropriate HTTP status codes (200 for success).
  </Step>

  <Step title="Process Asynchronously">
    Process webhook events asynchronously to respond quickly and avoid timeouts.
  </Step>

  <Step title="Monitor Delivery">
    Set up monitoring for webhook delivery failures and implement alerting.
  </Step>
</Steps>

## Rate Limiting

This endpoint is subject to the standard API rate limits:

* **Production**: 1000 requests per hour per API key
* **Development**: 100 requests per hour per API key

## Webhook Events

Common event types that webhooks receive include:

<Tabs>
  <Tab title="Payment Events">
    * `payment.completed` - Payment successfully processed
    * `payment.failed` - Payment processing failed
    * `payment.pending` - Payment is pending processing
    * `payment.refunded` - Payment has been refunded
  </Tab>

  <Tab title="Transfer Events">
    * `transfer.completed` - Transfer successfully completed
    * `transfer.failed` - Transfer processing failed
    * `transfer.pending` - Transfer is being processed
  </Tab>

  <Tab title="Invoice Events">
    * `invoice.created` - New invoice created
    * `invoice.paid` - Invoice has been paid
    * `invoice.overdue` - Invoice is overdue
    * `invoice.cancelled` - Invoice was cancelled
  </Tab>

  <Tab title="Customer Events">
    * `customer.created` - New customer registered
    * `customer.updated` - Customer profile updated
    * `customer.verified` - Customer KYC verification completed
  </Tab>
</Tabs>

## Related Endpoints

* `GET /api/v0/webhooks` - List all webhooks
* `GET /api/v0/webhooks/{id}` - Fetch specific webhook
* `PATCH /api/v0/webhooks/{id}` - Update webhook
* `DELETE /api/v0/webhooks/{id}` - Delete webhook
