# Create a webhook endpoint

> POST /webhooks: Create a webhook endpoint

`POST https://usedocs.app/v1/webhooks`

An HTTPS URL and the events to send. The response has the signing secret, shown once. Events: article.published, article.updated, article.unpublished, article.deleted, edit.proposed, draft.created, changelog_entry.published, task.completed, conversation.escalated, lead.created. Each delivery is signed: `usedocs-signature: t=…,v1=HMAC-SHA256(t.body)`.

## Authentication

Bearer token (`content:write`): A workspace API key: ud_live_…

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `bot_id` | query | `string` |  | Only for a key that covers several bots (see GET /bots). Or send the Usedocs-Bot header. |

## Request body

Required, `application/json`.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | `string` | Yes |  |
| `events` | `string[]` | Yes |  |

## Responses

| Status | Description |
| --- | --- |
| `201` | The endpoint, with secret. |
| `400` | The request is missing something or has a bad value. |
| `401` | No API key, or the key is revoked. |
| `402` | The workspace is paused; reads still work. |
| `403` | A read key on a write, or a key for another bot. |
| `404` | Not found. |
| `429` | Rate limited: 120 requests a minute per key, 30 tasks an hour. See Retry-After. |

## Response fields

| Field | Type | Description |
| --- | --- | --- |
| `id` | `string` |  |
| `url` | `string` |  |
| `events` | `string[]` |  |
| `enabled` | `boolean` |  |
| `created_at` | `string` |  |
| `secret_hint` | `string` |  |
| `secret` | `string` | Only when created or rotated. |