---
title: "Create Webhook Endpoint"
method: POST
path: "/v2/webhooks/endpoints"
tags: ["webhooks"]
---

# Create Webhook Endpoint

`POST /v2/webhooks/endpoints`

Register an HTTPS URL that receives a signed request when any indexing job in the organization finishes, in any environment. The payload's `data.environment` field says where the job ran.

The response includes `secret`, the signing secret the receiver uses to verify requests. It is returned only in this response and cannot be read back, so store it right away. If it is lost, rotate it.

Endpoints belong to the organization, and an API key from any of its environments sees and manages the same endpoints. An organization can have up to 20 endpoints. Filters combine with AND across `collection_ids`, `sync_ids` and `sources`, and OR within each list; the product of the non-empty list sizes must be at most 10. See the [Webhooks](/guides/webhooks) guide.

## Request body

- WebhookEndpointCreate
  - `collection_ids` string[], nullable — Only jobs that index into these collections, by collection id (up to 10). Empty or omitted means every collection.
  - `description` string, nullable — Free-text label, up to 200 characters.
  - `disabled` boolean — Create the endpoint without sending to it yet. Defaults to `false`.
  - `event_types` string[], nullable — Events to receive: any of `job.completed`, `job.completed_with_errors`, `job.failed`, `job.timed_out`, `job.cancelled`. Empty or omitted means all five.
  - `include_collection_name` boolean — Send `collection_name` in payloads. When any endpoint receiving an event turns this off, that event carries `collection_name: null`.
  - `sources` string[], nullable — Only jobs from these sources: `api` (started by a call to an index endpoint) or `sync` (started by a storage sync). Empty or omitted means both.
  - `sync_ids` string[], nullable — Only jobs started by these syncs (up to 10). Requires `sources` to include `sync` or be empty.
  - `url` string, required — HTTPS URL that receives events. Must start with `https://`, be reachable from the public internet, and be at most 2,048 characters.

## Response `201`

Successful Response

- WebhookEndpointWithSecret
  - `endpoint_id` string, required — The endpoint's id (`whe_...`).
  - `url` string, required — HTTPS URL that receives events.
  - `description` string, required — Free-text label. Empty string when not set.
  - `event_types` string[], required — Events this endpoint receives. Empty means all five.
  - `collection_ids` string[], required — Collection filter. Empty means every collection.
  - `sync_ids` string[], required — Sync filter. Empty means no sync filter.
  - `sources` string[], required — Source filter (`api`, `sync`). Empty means both.
  - `channels` string[], required — Filters set in Captain Studio's Webhooks page that cannot be expressed as `collection_ids`, `sync_ids` and `sources`. Empty for endpoints whose filters were set through the API. Setting `collection_ids`, `sync_ids` or `sources` with `PATCH` replaces them.
  - `include_collection_name` boolean, required — Whether payloads sent to this endpoint may carry `collection_name`.
  - `disabled` boolean, required — `true` when no events are being sent to this endpoint.
  - `disabled_reason` string, nullable, required — `delivery_failures` when Captain disabled the endpoint after sustained failed deliveries. `null` when it is enabled or was paused through the API.
  - `last_delivery` WebhookLastDelivery, required
    - `at` string, date-time, required — When the most recent delivery attempt finished.
    - `status` 'succeeded' | 'failed', required — Outcome of that delivery.
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required
  - `secret` string, required — The signing secret (`whsec_...`). Returned only in this response.

## Other responses

- `401` — Missing or invalid API key.
- `403` — The connection is read-only and cannot change webhooks (MCP connections without write access).
- `409` — Conflict with the endpoint's current state, or the organization already has 20 endpoints.
- `422` — A value was rejected. A route check returns `HTTP_ERROR` and names the value in `message`, for example `url must start with https://`. A malformed body returns `VALIDATION_ERROR` with one entry per field in `details`.
- `429` — `Too many webhook management requests. Try again shortly.` Retry after the `Retry-After` header.
- `503` — Webhooks are temporarily unavailable. Retry shortly.

## Changes

- **2026-09-24** `61a9364ad042` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/runcaptain/apis/api-reference/changes/v2/webhooks/endpoints/post.md)

---

[API](https://skmtc.dev/runcaptain/apis/api-reference.md) · [All operations](https://skmtc.dev/runcaptain/apis/api-reference/llms.txt) · [OpenAPI document](https://skmtc.dev/runcaptain/apis/api-reference/revisions/ac61e472bb7d?raw)
