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

# Create a webhook

> POST /v1/webhooks — register an endpoint to receive signed delivery events. The signing secret is returned exactly once.

Register an endpoint that receives signed event deliveries as email moves through the pipeline. The HMAC signing secret is returned once, on this call only.

**`POST /v1/webhooks`**

## Body

<ParamField body="url" type="string" required>
  HTTPS endpoint that receives the event POSTs. Each delivery is signed with the secret returned below.
</ParamField>

<ParamField body="eventTypes" type="string[]" required>
  Events to subscribe to. One or more of `accepted`, `queued`, `sending`, `sent`, `delivery`, `bounce`, `complaint`, `open`, `click`, `delivery_delayed`, `rejected`, `rendering_failure`, `failed`, `inbound_received`, `inbound_rejected`.
</ParamField>

<Warning>
  **The secret is shown once.** `signingSecret` is returned only on this response and is redacted on every later read. Store it now. If you lose it, delete the endpoint and create a new one.
</Warning>

## Request

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.drin.run/v1/webhooks \
    -H "Authorization: Bearer $DRIN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://example.com/hooks/drin",
      "eventTypes": ["delivery", "bounce", "complaint"]
    }'
  ```

  ```typescript Node.js theme={null}
  import { DrinClient } from "@drin00/sdk";

  const drin = new DrinClient({ apiKey: process.env.DRIN_API_KEY });

  const hook = await drin.webhooks.create({
    url: "https://example.com/hooks/drin",
    eventTypes: ["delivery", "bounce", "complaint"],
  });

  // Store this now — it is never shown again.
  console.log(hook.signingSecret);
  ```

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

  requests.post(
      "https://api.drin.run/v1/webhooks",
      headers={"Authorization": f"Bearer {os.environ['DRIN_API_KEY']}"},
      json={
          "url": "https://example.com/hooks/drin",
          "eventTypes": ["delivery", "bounce", "complaint"],
      },
  ).raise_for_status()
  ```
</CodeGroup>

## Response

Returns `201 Created` with the endpoint. New endpoints start `enabled`.

```json 201 Created theme={null}
{
  "id": "wh_3kQ9p2",
  "url": "https://example.com/hooks/drin",
  "enabled": true,
  "eventTypes": ["delivery", "bounce", "complaint"],
  "signingSecret": "whsec_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"
}
```

<Tip>
  **Verify deliveries.** The SDK ships a constant-time verifier: `drin.webhooks.verify(rawBody, header, signingSecret)` checks the `Drin-Signature` header and returns the parsed payload. See [Webhooks](/webhooks).
</Tip>
