# Subscribe a URL to events

`POST /v1/webhooks`

Requires an API key with the `webhooks:write` scope. [About keys and scopes](/docs/api/authentication)

Registers an HTTPS endpoint for the listed events, or `*` for every event including ones added later. Deliveries are signed with the returned `secret` (shown only here), retried with backoff, and paused by a circuit breaker while the endpoint keeps failing; see the webhooks guide. This is the subscribe call Zapier, Make and n8n make when a workflow turns on. A URL already subscribed returns 409 `ALREADY_EXISTS`; edit its events instead. Agent keys cannot hold `webhooks:write`.

## Request body

- `url` (string, required, uri, up to 2000 characters) — The HTTPS endpoint that receives deliveries; it must resolve to a public host.
- `events` (string[], required, at least 1 item, at most 14 items) — Event types to receive, or `["*"]` alone for every event, including future ones.
- `source` (string, optional, one of `zapier`, `make`, `n8n`, `http_api`) — The tool subscribing (`zapier`, …), so the dashboard can say who made it.

## Returns

Returns `201 Created` with a `CreatedWebhook` in `data`. Otherwise returns an error; [Errors](/docs/api/errors) lists every code and which to retry.

- `id` (string, required, uuid)
- `url` (string, required, uri)
- `events` (string[], required) — The event types it receives.
- `source` (string | null, required, one of `zapier`, `make`, `n8n`, `http_api`) — The integration that created it; null when created directly.
- `status` (string, required, one of `active`, `paused`, `disabled`) — `disabled` is set only by the platform; `active` re-enables it.
- `previousSecretExpiresAt` (string | null, required, date-time) — Until when the replaced secret still signs requests after a rotation.
- `circuitOpenUntil` (string | null, required, date-time) — While set and in the future, deliveries to this endpoint wait: it failed five requests in a row. The next request after it is a probe; a success clears it.
- `createdAt` (string, required, date-time)
- `secret` (string, required) — Signs every delivery; shown once, here.

## Example

```bash
curl -X POST https://api.kirora.io/v1/webhooks \
  -H "Authorization: Bearer $KIRORA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "events": [
      "*"
    ]
  }'
```

Response `201`:

```json
{
  "data": {
    "id": "018f2a4e-6b1c-7d3e-9f40-37386ae05a6b",
    "url": "https://example.com",
    "events": [
      "*"
    ],
    "source": "zapier",
    "status": "active",
    "previousSecretExpiresAt": "2030-03-14T09:30:00Z",
    "circuitOpenUntil": "2030-03-14T09:30:00Z",
    "createdAt": "2030-03-14T09:30:00Z",
    "secret": "secret_example"
  }
}
```
