IntegrationsWebhooks
Managing Endpoints
Create and delete webhook endpoints on Kaiten Cloud in the console, update them over the API, and read each endpoint's signing secret — where your License includes webhooks.
A webhook endpoint is an HTTPS URL plus the list of event types it subscribes to. Endpoints are managed in the console under Integrations → Webhooks, which creates and deletes them, or over the API, which also updates them, with a service-account token carrying the webhooks scope.
Included in your License
Webhooks are counted by the event, not by the endpoint. Your organization's own Kaiten Cloud License grants a monthly allowance of published events, the webhooks entitlement, which resets every calendar month. Endpoints cost nothing: create as many as you need. What counts is each event sent to them.
Every webhooks route — the delivery history too — first reads that grant. Any grant serves the routes, unlimited included, except one of no events:
| Answer | Code | Meaning |
|---|---|---|
403 | Webhooks.NotEntitled | The License grants no webhook events. The console hides the Webhooks pages for the same reason: it shows them only where GET /webhooks answers. |
503 | Webhooks.EntitlementVerificationUnavailable | The grant could not be read. Nothing is decided: retry the request. |
The allowance is spent as events are published, and going past it never stops a delivery: the event goes out and is recorded as overuse. An event is held back in two cases only. When the License grants no webhook events, it is not delivered. When the allowance cannot be checked at the moment the event is published, the event waits and is tried again, rather than dropped.
The License is checked before the token's scopes: in an organization whose License does not include webhooks, every token gets this 403, whatever it carries. A token that lacks the scope answers 403 too, with a different code — the field of the problem document to branch on.
In the console
Open Integrations → Webhooks. The Events tab lists your endpoints — the events each one subscribes to, its signing secret (masked, with a reveal control), and its creation date. The History tab is the delivery history.
Click New Webhook. Tick the events to subscribe to — they are grouped by domain, with the event name shown next to each label — and paste your HTTPS URL into Webhook URL.
Click Create Webhook. The endpoint receives a POST for every subscribed event from now on. Copy the signing secret from the list before you go to production: verifying signatures explains what to do with it.
Over the API
The endpoint routes live under /webhooks on the Kaiten Cloud API, https://app.kaiten.sh/api. The examples read it from $KAITEN_API, and the token from $KAITEN_TOKEN, as the quickstart does:
export KAITEN_API="https://app.kaiten.sh/api"Reads require read:webhooks, writes write:webhooks.
Create an endpoint
curl -X POST "$KAITEN_API/webhooks" \
-H "Authorization: Bearer $KAITEN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.example.com/kaiten-webhook",
"eventTypes": ["com.kaiten.customer.v1.created", "com.kaiten.instance.entitlement.v1.usage_reached"]
}'| Field | Type | Required | Description |
|---|---|---|---|
url | string | yes | The HTTPS endpoint that receives deliveries |
eventTypes | string[] | yes | Event types from the catalog — the endpoint receives these and nothing else |
Use the catalog's Type column (com.kaiten.customer.v1.created, com.kaiten.instance.v1.created, …), not the event names. The endpoint's filter is exactly the set of types you list, and there is no "all events" subscription:
| Answer | Code | Cause |
|---|---|---|
400 | CreateWebhook.MissingURL | url is missing |
400 | CreateWebhook.MissingEventTypes | eventTypes is missing or empty — which is also what a body that still sends eventNames gets, since that key is ignored |
400 | CreateWebhook.InvalidEventTypes | An entry is not an event type: an event name such as CUSTOMER_CREATED, or a typo |
The 201 response is the endpoint — id, url, eventTypes, createdAt, updatedAt. It does not carry the signing secret: read the endpoint for it.
List endpoints
curl "$KAITEN_API/webhooks" \
-H "Authorization: Bearer $KAITEN_TOKEN"An array of endpoints, each with its id, url and eventTypes, and without its signing secret.
Read one endpoint
curl "$KAITEN_API/webhooks/{id}" \
-H "Authorization: Bearer $KAITEN_TOKEN"The endpoint with its signingSecret. This is the only route that returns the secret.
Update an endpoint
Updating is an API operation: the console creates and deletes endpoints, and has no edit form.
curl -X PUT "$KAITEN_API/webhooks/{id}" \
-H "Authorization: Bearer $KAITEN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.example.com/kaiten-webhook",
"eventTypes": [
"com.kaiten.customer.v1.created",
"com.kaiten.customer.v1.updated",
"com.kaiten.instance.entitlement.v1.usage_reached"
]
}'PUT replaces the endpoint's definition. url and a non-empty eventTypes are both required, and the list you send becomes the endpoint's whole filter: a type you leave out is unsubscribed. Send the complete list of event types you want, not the difference. The refusals are those of creation, under UpdateWebhook.. An update does not touch the Slack formatting decided when the endpoint was created.
Delete an endpoint
curl -X DELETE "$KAITEN_API/webhooks/{id}" \
-H "Authorization: Bearer $KAITEN_TOKEN"Deliveries to the endpoint stop.
Delivery history
curl "$KAITEN_API/webhooks/history" \
-H "Authorization: Bearer $KAITEN_TOKEN"The same view as the console's History tab: the 50 most recent delivery attempts of each endpoint, returned in one response as { "history": [...] }. There is no pagination, so older attempts are not reachable. Each entry carries date, hookId, hookUrl, eventType, status, and — once the endpoint has answered — responseStatusCode and responseStatusText. Statuses and retries: delivery and retries.
The signing secret
Each endpoint has its own signing secret. The console shows it masked in the endpoint list, with a reveal control; over the API, GET /webhooks/{id} returns it as signingSecret, and neither the create response nor the list carries it. Store it with the service that receives the deliveries; it is the key your handler verifies every delivery against — verifying signatures.
Where to go next
Choose what to subscribe to in the event catalog, then read what a delivery looks like in the payload examples. The first end-to-end delivery, step by step: receive events.
Overview
Managed webhook endpoints on Kaiten Cloud — subscribe an HTTPS endpoint to any of the 55 domain events, with signed deliveries, retries, and a delivery history. Self-hosted stacks consume the same events from RabbitMQ.
Event Catalog
All 55 domain events Kaiten emits, across 10 domains — names, versioned types, what triggers each one, and the payload contract it carries.