---
title: "Create a webhook endpoint"
method: POST
path: "/endpoints"
tags: ["Endpoints"]
---

# Create a webhook endpoint

`POST /endpoints`

Creates a new webhook endpoint. If a deactivated endpoint
with the same URL and domain exists, it is reactivated
instead. Subject to plan limits on the number of active
endpoints.

**Signing is account-scoped, not per-endpoint.** This call
does not return any signing material; every endpoint on the
account uses the same webhook secret, fetched via
`GET /account/webhook-secret`. See the API-level "Webhook
signing" section for the full wire format (header name,
signed string, hash algo, secret format, tolerance) and a
language-agnostic verification recipe.

After creating the endpoint, fire a test delivery against
it via `POST /endpoints/{id}/test` to confirm your verifier
accepts the signature.

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `kind` 'http' | 'function' — http: deliver to a webhook URL (provide url). function: invoke a Primitive Function (provide function_id, omit url).
  - `url` string — The webhook URL to deliver events to. Required when kind is http; omit for function endpoints.
  - `function_id` string, uuid — The Function to invoke. Required when kind is function.
  - `enabled` boolean — Whether the endpoint is active
  - `domain_id` string, uuid, nullable — Restrict to emails from a specific domain
  - `rules` object — Endpoint-specific filtering rules
  - `is_route_target` boolean — Create this endpoint as a route-target: reachable only via an explicit recipient route, never a domain's default destination, and exempt from the one-endpoint-per-domain rule.

## Response `201`

Endpoint created (or reactivated)

- object
  - `success` true, required
  - `data` object, required
    - `id` string, uuid, required
    - `org_id` string, uuid, required
    - `url` string, nullable
    - `enabled` boolean, required
    - `domain_id` string, uuid, nullable — Restrict this endpoint to emails from a specific domain
    - `rules` object, required — Endpoint-specific filtering rules
    - `created_at` string, date-time, required
    - `updated_at` string, date-time, required
    - `delivery_count` integer, required — Total webhook deliveries attempted
    - `success_count` integer, required — Successful deliveries
    - `failure_count` integer, required — Failed deliveries
    - `consecutive_fails` integer, required — Current streak of consecutive failures
    - `last_delivery_at` string, date-time, nullable
    - `last_success_at` string, date-time, nullable
    - `last_failure_at` string, date-time, nullable
    - `deactivated_at` string, date-time, nullable
    - `kind` 'http' | 'function' — http: deliver to the webhook URL. function: invoke a Primitive Function.
    - `function_id` string, uuid, nullable — The Function this endpoint invokes, when kind is function.
    - `is_route_target` boolean — When true, this endpoint is reachable only via an explicit recipient route, never as a domain's default destination, and is exempt from the one-endpoint-per-domain rule (so many can share a domain).

## Other responses

- `400` — Invalid request parameters
- `401` — Invalid or missing API key

---

[API](https://skmtc.dev/primitive/apis/primitive-api.md) · [All operations](https://skmtc.dev/primitive/apis/primitive-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/primitive/primitive-api/revisions/c2299d28022c/schema)
