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

# Create Webhook

> Create a new webhook endpoint

## Overview

Create a new webhook endpoint to receive order, trade, and deposit event notifications. The webhook secret is only returned once at creation, so make sure to store it securely.

<Info>
  Pro webhook setup is support-managed. Contact [support@daya.co](mailto:support@daya.co) to enable webhook setup or request webhook configuration changes for your Pro account.
</Info>

## Authentication

<ParamField header="X-Api-Key" type="string" required>
  Your API key with Write scope

  ```
  X-Api-Key: daya_sk_YOUR_API_KEY
  ```
</ParamField>

## Request Body

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

  **Example:** `https://example.com/webhooks/daya`
</ParamField>

<ParamField body="events" type="array" required>
  Events to subscribe to (at least one required)

  **Allowed values:** `order.created`, `order.filled`, `order.partially_filled`, `order.cancelled`, `order.rejected`, `trade.executed`, `deposit.completed`, `crypto.deposit.completed`
</ParamField>

<ParamField body="description" type="string">
  Optional description for the webhook

  **Example:** `My order notifications`
</ParamField>

## Request Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://api.pro.daya.co/public/v1/webhooks' \
    --header 'X-Api-Key: daya_sk_YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
      "url": "https://example.com/webhooks/daya",
      "events": ["order.filled", "order.cancelled", "trade.executed"],
      "description": "Order and trade notifications"
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://api.pro.daya.co/public/v1/webhooks',
    {
      method: 'POST',
      headers: {
        'X-Api-Key': 'daya_sk_YOUR_API_KEY',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        url: 'https://example.com/webhooks/daya',
        events: ['order.filled', 'order.cancelled', 'trade.executed'],
        description: 'Order and trade notifications'
      })
    }
  );

  const data = await response.json();
  // IMPORTANT: Store the secret securely - it's only shown once!
  console.log('Webhook secret:', data.data.secret);
  ```

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

  headers = {
      'X-Api-Key': 'daya_sk_YOUR_API_KEY',
      'Content-Type': 'application/json'
  }

  payload = {
      'url': 'https://example.com/webhooks/daya',
      'events': ['order.filled', 'order.cancelled', 'trade.executed'],
      'description': 'Order and trade notifications'
  }

  response = requests.post(
      'https://api.pro.daya.co/public/v1/webhooks',
      headers=headers,
      json=payload
  )

  result = response.json()
  # IMPORTANT: Store the secret securely - it's only shown once!
  print(f"Webhook secret: {result['data']['secret']}")
  ```

  ```go Go theme={null}
  package main

  import (
      "bytes"
      "encoding/json"
      "fmt"
      "net/http"
  )

  func main() {
      payload := map[string]interface{}{
          "url":         "https://example.com/webhooks/daya",
          "events":      []string{"order.filled", "order.cancelled", "trade.executed"},
          "description": "Order and trade notifications",
      }
      jsonPayload, _ := json.Marshal(payload)

      req, _ := http.NewRequest("POST", "https://api.pro.daya.co/public/v1/webhooks", bytes.NewBuffer(jsonPayload))
      req.Header.Set("X-Api-Key", "daya_sk_YOUR_API_KEY")
      req.Header.Set("Content-Type", "application/json")

      client := &http.Client{}
      resp, err := client.Do(req)
      if err != nil {
          panic(err)
      }
      defer resp.Body.Close()

      var result map[string]interface{}
      json.NewDecoder(resp.Body).Decode(&result)
      // IMPORTANT: Store the secret securely - it's only shown once!
      fmt.Println("Webhook created:", result["data"])
  }
  ```
</CodeGroup>

## Response

<ResponseField name="success" type="boolean" required>
  Indicates if the request was successful
</ResponseField>

<ResponseField name="message" type="string" required>
  Human-readable response message
</ResponseField>

<ResponseField name="data" type="object" required>
  Created webhook with secret

  <Expandable title="webhook properties">
    <ResponseField name="id" type="string">
      Unique webhook identifier (UUID)
    </ResponseField>

    <ResponseField name="url" type="string">
      Webhook endpoint URL
    </ResponseField>

    <ResponseField name="description" type="string">
      Webhook description
    </ResponseField>

    <ResponseField name="events" type="array">
      Events this webhook is subscribed to
    </ResponseField>

    <ResponseField name="status" type="string">
      Webhook status (will be `active`)
    </ResponseField>

    <ResponseField name="secret" type="string">
      **Signing secret for verifying webhook payloads.**

      <Warning>
        This is only returned once at creation. Store it securely!
      </Warning>
    </ResponseField>

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

    <ResponseField name="updated_at" type="string">
      ISO 8601 last update timestamp
    </ResponseField>
  </Expandable>
</ResponseField>

### Success Response

<ResponseExample>
  ```json 201 Created theme={null}
  {
    "success": true,
    "message": "Webhook created successfully",
    "data": {
      "id": "770e8400-e29b-41d4-a716-446655440000",
      "url": "https://example.com/webhooks/daya",
      "description": "Order and trade notifications",
      "events": ["order.filled", "order.cancelled", "trade.executed"],
      "status": "active",
      "secret": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456",
      "failure_count": 0,
      "last_success_at": null,
      "last_failure_at": null,
      "last_failure_reason": null,
      "created_at": "2024-01-15T10:00:00Z",
      "updated_at": "2024-01-15T10:00:00Z"
    },
    "timestamp": "2024-01-15T10:00:00Z"
  }
  ```
</ResponseExample>

<Note>
  The `secret` is a 64-character hex string (32 bytes). This is the raw secret used for HMAC-SHA256 signature verification.
</Note>

## Error Responses

<ResponseExample>
  ```json 400 Bad Request - Invalid URL theme={null}
  {
    "success": false,
    "message": "Validation error",
    "error": {
      "code": "VALIDATION_ERROR",
      "message": "URL must be a valid HTTPS URL"
    }
  }
  ```

  ```json 400 Bad Request - Invalid events theme={null}
  {
    "success": false,
    "message": "Validation error",
    "error": {
      "code": "VALIDATION_ERROR",
      "message": "At least one event is required"
    }
  }
  ```

  ```json 401 Unauthorized theme={null}
  {
    "success": false,
    "message": "Unauthorized",
    "error": {
      "code": "API_KEY_INVALID",
      "message": "The provided API key is invalid"
    }
  }
  ```

  ```json 429 Too Many Requests - Webhook limit theme={null}
  {
    "success": false,
    "message": "Webhook limit exceeded",
    "error": {
      "code": "WEBHOOK_LIMIT_EXCEEDED",
      "message": "Maximum number of webhooks reached (5)"
    }
  }
  ```
</ResponseExample>

## Available Events

| Event                      | Description                                                  |
| -------------------------- | ------------------------------------------------------------ |
| `order.created`            | New order accepted by matching engine                        |
| `order.filled`             | Order completely filled                                      |
| `order.partially_filled`   | Order partially executed                                     |
| `order.cancelled`          | Order cancelled                                              |
| `order.rejected`           | Order rejected                                               |
| `trade.executed`           | Trade executed involving your order                          |
| `deposit.completed`        | NGN bank-transfer deposit settled to your Daya Pro balance   |
| `crypto.deposit.completed` | Confirmed on-chain deposit credited to your Daya Pro balance |

## Important Notes

<Warning>
  **Store your webhook secret securely!** The `secret` field is only returned once when the webhook is created. If you lose it, you'll need to [rotate the secret](/pro/api-reference/rotate-webhook-secret).
</Warning>

<Note>
  Webhook URLs must use HTTPS in production. HTTP is only allowed for local development testing.
</Note>

## Rate Limits

* **100 requests per minute** per API key
* **Maximum 5 webhooks** per account

## Next Steps

<CardGroup cols={2}>
  <Card title="Webhook Verification" icon="shield-check" href="/pro/webhooks/verification">
    Learn how to verify webhook signatures
  </Card>

  <Card title="Webhook Events" icon="bell" href="/pro/webhooks/events">
    See event payload details
  </Card>

  <Card title="List Webhooks" icon="list" href="/pro/api-reference/list-webhooks">
    View all your webhooks
  </Card>

  <Card title="Update Webhook" icon="pen" href="/pro/api-reference/update-webhook">
    Update webhook configuration
  </Card>
</CardGroup>
