Register a webhook endpoint
const url = 'https://example.com/v1/webhook-endpoints';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"url":"https://example.com","events":["run.finished"],"filter":{"projectId":"example","flowIds":["example"],"includeDryRuns":true},"secretRef":{"envName":"example","name":"example"},"description":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://example.com/v1/webhook-endpoints \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "url": "https://example.com", "events": [ "run.finished" ], "filter": { "projectId": "example", "flowIds": [ "example" ], "includeDryRuns": true }, "secretRef": { "envName": "example", "name": "example" }, "description": "example" }'Registers a URL the platform sends signed events to. The signing secret is shared with the receiver, so it lives in your secrets (.env in development, the secrets store in production) and the endpoint references it by name (secretRef). Store it first; POST /v1/webhook-endpoints/generate-secret makes a strong one. Deliveries are signed in the Standard Webhooks format (webhook-id, webhook-timestamp, webhook-signature); verify with verifyWebhook from @kindgi/crypto or any Standard Webhooks library. The event bodies are described under webhooks in this document.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Header Parameters
Section titled “Header Parameters”Caller-supplied idempotency key. Retries with the same key return the original response byte-identical (per docs/API-ROUTE-CONVENTIONS.md §3.1).
Request Bodyrequired
Section titled “Request Bodyrequired”object
Absolute https URL (http only where the deployment allows it, e.g. development). No credentials in the URL. The deployment may refuse private network addresses (400 webhook-url-refused).
Which events reach the endpoint. Every field narrows; absent fields do not. run.finished is sent for top-level runs only.
object
Only runs in this project.
Only runs of these flows (any version).
Dry runs are left out unless this is true.
A secret by name in the deployment’s secrets store, resolved at tenant scope (the same shape as a provider’s secret_ref). The value is whsec_ + base64 of at least 24 random bytes (or that base64 alone); the store keeps it, the endpoint keeps only this reference.
object
Responses
Section titled “Responses”Endpoint registered.
object
Which events reach the endpoint. Every field narrows; absent fields do not. run.finished is sent for top-level runs only.
object
Only runs in this project.
Only runs of these flows (any version).
Dry runs are left out unless this is true.
A secret by name in the deployment’s secrets store, resolved at tenant scope (the same shape as a provider’s secret_ref). The value is whsec_ + base64 of at least 24 random bytes (or that base64 alone); the store keeps it, the endpoint keeps only this reference.
object
Example
{ "events": [ "run.finished" ]}Malformed body or unknown field; the deployment refuses the URL (webhook-url-refused); the referenced secret does not exist (webhook-secret-not-found) or is too weak (webhook-secret-too-weak).
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}Missing / malformed / expired / revoked bearer token.
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}filter.projectId names no project (project-not-found).
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}Idempotency-Key was reused with a different body, or resource-state conflict.
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}Server error (unmapped domain code or framework crash).
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}