For the complete documentation index, see llms.txt. This page is also available as Markdown.

Webhooks

Receive authenticated events from external systems in ZenML.

Webhooks connect external systems to ZenML so that your ZenML deployment can react to events that happen outside the platform. For example, you can receive an event when a pull request is merged in GitHub, when a ClickUp task changes status, when someone requests a deployment in Slack, or when an internal service publishes a new model version.

When you create a webhook, ZenML exposes a project-scoped intake URL. Configure the external system to send signed HTTP requests to that URL.

For every delivery, the webhook endpoint:

  1. verifies the request signature using the webhook's signing secret;

  2. validates the headers and JSON payload required by that webhook type;

  3. records intake statistics for accepted and rejected deliveries; and

  4. sends the provider-selected successful response; and

  5. makes any accepted event available to configured consumers in a background task after the response is sent.

Consumers define how ZenML reacts to accepted events. For example, a webhook trigger can filter GitHub, ClickUp or Slack events and execute attached pipeline snapshots when a pull request is merged or a task status changes, a deployment message is posted, or an approval reaction is added.

When at least one webhook trigger matches, ZenML retains the original JSON request body so directly triggered pipeline steps can retrieve fields omitted from the normalized semantic event. Request headers are not retained. See Access the raw webhook body.

The endpoint returns an HTTP response selected by the provider. GitHub and custom deliveries normally return 202 Accepted; Slack returns 200 OK. An invalid signature, invalid payload, missing webhook, or inactive webhook returns an appropriate 4xx response. The response reports the result of webhook intake. Any work performed by consumers happens in an in-process background task after the response is sent.

Available providers

Provider
Type
Authentication
Event model

Slack

slack

Slack request signature and timestamp

Curated semantic Slack automation events and typed filters

GitHub

github

GitHub HMAC-SHA256 signature

Curated semantic GitHub events and string filters

ClickUp

clickup

ClickUp HMAC-SHA256 signature

Curated ClickUp task and list events and string filters

Custom webhooks

custom

ZenML HMAC-SHA256 signature

User-supplied event name and JSON object

Provider pages describe the headers, event model, external setup, and manual testing procedure for each provider.

Manage webhooks

Webhooks are project-scoped resources. Their basic lifecycle is create, inspect, update, and delete.

Create a webhook

Choose a name and provider type to create a webhook in the active project:

The equivalent SDK flow is:

Provider types are string identifiers. ZenML includes github, clickup, slack, and custom; servers may register additional provider implementations, and reject provider types that are not registered.

The provider type determines how deliveries are authenticated and interpreted and cannot be changed after creation. By default, ZenML also generates a signing secret. Capture it as described in Manage signing credentials.

Describe and list webhooks

Describe one webhook by name or ID, or list the webhooks in the active project:

describe includes the complete endpoint URL. Use that value when configuring the external provider instead of constructing the URL manually.

With the SDK, get_webhook accepts a name, ID, or ID prefix. list_webhooks supports filters such as provider type and active state:

Normal describe, get, and list responses never include the signing secret.

Update a webhook

You can rename a webhook or change its active state. These are the only mutable webhook properties:

Via the SDK:

The webhook ID, project association, and provider type cannot be updated. The endpoint path is derived from the provider type and webhook ID. An inactive webhook rejects otherwise valid deliveries with 409 Conflict. Changing the webhook's active state does not change the active state or configuration of its consumers.

Delete a webhook

Delete a webhook by name or ID:

Via the SDK:

ZenML rejects deletion while a non-archived webhook trigger references the webhook. Archive or permanently delete those triggers before deleting the webhook. Archived trigger history and its serialized configuration are retained.

Manage signing credentials

Every webhook has one active signing secret. The sender uses it to sign the exact request body, and ZenML uses it to authenticate the delivery. The secret is write-only after it is created or rotated: normal webhook responses never expose it.

Secret visibility depends on the operation:

Operation
CLI behavior
SDK behavior

Create with a generated secret

Prints the secret once

Returns it once as result.secret

Create with a user-supplied secret

Does not print the secret

result.secret is None

Rotate to a generated secret

Prints the replacement once

Returns it once as result.secret

Rotate to a user-supplied secret

Prints the active replacement

Returns it once as result.secret

Describe, get, or list

Never exposes the secret

Never exposes the secret

Use a ZenML-generated secret

When you omit --secret, ZenML generates a secret and the CLI prints it once as part of the create command:

Store the printed value securely before leaving the command output. With the SDK, the generated secret is available only on the create result:

Subsequent calls to get_webhook or list_webhooks do not return it.

Provide your own secret

If an existing credential-management workflow needs to choose the value, pass it during creation:

Via the SDK:

ZenML does not echo a user-supplied secret. The CLI does not print it, and result.secret is None in the SDK.

Rotate a signing secret

Generate a replacement signing secret with:

Or provide the replacement yourself:

Via the SDK:

The replacement secret is returned once. The previous secret stops authenticating deliveries as soon as rotation completes, so update the external provider with the replacement to resume delivery.

Understand delivery responses

Webhook endpoints return intake-level responses:

Status
Meaning

200 OK

The provider accepted the delivery and selected an immediate success response. Slack uses this for event and control deliveries.

202 Accepted

The delivery was accepted for processing, or the provider intentionally ignored an unsupported event before webhook lookup.

400 Bad Request

Required provider metadata is missing, or the body is not a valid top-level JSON object.

401 Unauthorized

The signature does not match the exact request body.

404 Not Found

The webhook does not exist, or the provider in the URL does not match its stored type.

409 Conflict

The authenticated webhook is inactive.

For signed requests, the sender and ZenML must calculate the signature over the same raw bytes. Reformatting JSON or adding a trailing newline after calculating the signature changes those bytes and causes authentication to fail.

Provider-specific early handling can refine this behavior. For example, GitHub deliveries with a non-empty but unsupported X-GitHub-Event value return 202 without resolving a webhook. See the GitHub and ClickUp providers for details. Slack authenticates and acknowledges URL-verification and rate-limit control deliveries with 200, but does not create events for consumers. See the Slack provider for its complete envelope behavior.

Successful intake schedules event handlers in an in-process background task. It does not guarantee that a handler starts or completes, and the handoff is not durable if the server process stops after sending the response.

Inspect intake statistics

Hydrated webhook details include intake statistics that help answer whether a provider is reaching and authenticating with ZenML:

  • received, accepted, authentication-failed, and invalid-payload counts;

  • the last received and accepted timestamps;

  • the last error timestamp and a bounded error summary.

The CLI describe command and the SDK get_webhook method return hydrated details by default:

These statistics cover intake only. They do not report consumer matches, queue publication, pipeline run creation, or run outcomes.

Next steps

Last updated

Was this helpful?