Skip to content

Update a webhook ​

PATCH/api/v2/workspaces/{slug}/webhooks/{pk}/

Change a webhook's URL, event scopes, filters, or other settings. Send only the keys you want to change. Omitted keys keep their current value, and an explicit null clears a nullable field.

Path Parameters ​

slug:requiredstring

The workspace slug. It appears in your Plane URLs. In https://app.plane.so/my-team/projects/, the slug is my-team.

pk:requiredstring (uuid)

The webhook id.

Body Parameters ​

Every field is optional. Send the subset you're changing.

url:optionalstring (uri)

The endpoint Plane posts events to. It must be a publicly reachable http or https URL, and it must be unique within the workspace.

name:optionalstring

Display name.

Maximum 255 characters. Nullable.

scopes:optionalarray of string

The complete list of events the webhook receives, such as workitem.created or cycle.updated. The list you send replaces the current one. An unknown scope returns 400.

is_active:optionalboolean

Whether Plane delivers events to the webhook.

content_type:optionalstring
  • application/json - application/json
  • application/x-www-form-urlencoded - application/x-www-form-urlencoded

One of application/json, application/x-www-form-urlencoded.

version:optionalstring

The payload version, for example v2.

Maximum 10 characters.

rich_filters:optionalobject

A structured filter that replaces the current one, for example {"priority__in": ["urgent", "high"]}. Send {} to remove it. See Rich filters.

A function Plane can't evaluate against an event returns 400.

pql_filters:optionalobject

A PQL filter that replaces the current one, as {"stripped": "<query>"}. Send {"stripped": ""} to remove it. See PQL filters.

The request returns 400 if the value isn't an object with a string stripped, if the query has invalid syntax, or if the query uses a function that needs a signed-in user, such as currentUser().

last_used_filter:optionalstring

Which filter Plane evaluates when it delivers an event: rich_filters or pql_filters. Plane evaluates only this one.

Plane doesn't validate the value. Any value other than pql_filters makes Plane evaluate rich_filters.

If you send exactly one of rich_filters and pql_filters and leave this out, Plane switches it to the filter you sent. For example, a request with only rich_filters moves a webhook that used its PQL filter over to the rich filter.

Response shaping ​

fields:optionalstring

Comma-separated list of fields to return. Unrequested keys are omitted, not returned as null. id always comes back. Pass all for every requestable field. An unknown name is a 400. See Sparse fields.

Requestable here: content_type, created_at, created_by_id, id, is_active, last_used_filter, name, pql_filters, rich_filters, scopes, updated_at, updated_by_id, url, version.

Scopes ​

webhooks:write

Errors ​

StatusCodeCause
400invalid_requestThe URL isn't allowed, a scope is unknown, or a filter is invalid or can't be evaluated.
401unauthorizedMissing or invalid credentials.
402payment_requiredThe feature this endpoint belongs to isn't enabled on your plan or is switched off.
403forbiddenYour role or token scope doesn't allow this.
404not_foundNo such resource, or it's outside your tenant.
406not_acceptableThe Accept header asks for a representation the API can't produce.
409conflictAnother webhook in the workspace already uses this URL.
413payload_too_largeThe request body is over the size limit.
415unsupported_media_typeThe Content-Type isn't one this endpoint accepts.
429rate_limitedThrottled. Honor the Retry-After header before retrying.
Update a webhook
bash
curl -X PATCH \
  "https://api.plane.so/api/v2/workspaces/my-team/webhooks/9c1f0b3d-6d2e-4c9a-8b41-2f7e5a0d6c88/" \
  -H "X-Api-Key: $PLANE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "rich_filters": {"priority__in": ["urgent", "high"]}
}'
Response200
json
{
  "id": "9c1f0b3d-6d2e-4c9a-8b41-2f7e5a0d6c88",
  "name": "Urgent work items to on-call",
  "url": "https://hooks.example.com/plane/urgent",
  "is_active": true,
  "version": "v2",
  "content_type": "application/json",
  "scopes": ["workitem.created", "workitem.updated"],
  "last_used_filter": "rich_filters",
  "rich_filters": {
    "priority__in": ["urgent", "high"]
  },
  "pql_filters": {
    "stripped": "priority = \"urgent\""
  },
  "created_at": "2026-01-14T09:22:41.478363Z",
  "updated_at": "2026-02-03T16:45:12.904117Z",
  "created_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430",
  "updated_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430"
}
Response404
json
{
  "type": "not_found",
  "code": "not_found",
  "detail": "The requested resource was not found."
}