---
title: "Update a webhook subscription’s url, events, filters, or status. Each field you include is replaced wholesale (a partial update at the top level, not a deep merge): sending filters replaces the entire filters object — e.g. PATCH { \"filters\": { \"only_my_bubbles\": false } } drops a previously-set bubble_types — and an empty { \"filters\": {} } clears all filters. Omit a field to leave it unchanged. status accepts \"active\" only — used to re-enable a subscription auto-disabled after repeated delivery failures; there is no manual disable. Requires the webhooks:manage scope."
method: PATCH
path: "/v1/webhooks/{id}"
---

# Update a webhook subscription’s url, events, filters, or status. Each field you include is replaced wholesale (a partial update at the top level, not a deep merge): sending filters replaces the entire filters object — e.g. PATCH { "filters": { "only_my_bubbles": false } } drops a previously-set bubble_types — and an empty { "filters": {} } clears all filters. Omit a field to leave it unchanged. status accepts "active" only — used to re-enable a subscription auto-disabled after repeated delivery failures; there is no manual disable. Requires the webhooks:manage scope.

`PATCH /v1/webhooks/{id}`

## Request

- Base URL: `https://api.usebubbles.com`
- URL: `https://api.usebubbles.com/v1/webhooks/{id}`
- Auth: HTTP bearer

## Path parameters

- `id` string, required

## Request body

- UpdateWebhookRequest: PATCH /v1/webhooks/{id} request body — all fields optional. status accepts "active" only (re-enable).
  - `url` string: A new receiver URL.
  - `events` string[]: A new event set.
  - `status` 'active': Set to "active" to re-enable an auto-disabled subscription.

## Response `200`

Success.

- WebhookSubscription: A webhook subscription (GET /v1/webhooks[/{id}]); the signing secret is omitted.
  - `id` string, required: The subscription id (wh_…).
  - `url` string, required: The receiver URL deliveries are POSTed to.
  - `events` string[], required: Subscribed event types (bubble.ready | meeting_recording.ready | screen_recording.ready).
  - `team_id` string, nullable, required: Team scope, or null (all teams).
  - `space_id` string, nullable, required: Channel scope, or null.
  - `filters` WebhookSubscriptionFilters, required: Optional post-match filters on a webhook subscription.
    - `bubble_types` string[]: Only deliver for these bubble types.
    - `only_my_bubbles` boolean: Only deliver for bubbles the subscriber created.
  - `status` 'active' | 'disabled', required: Delivery status; auto-disabled after repeated failures.
  - `created_at` string, required: Creation instant (ISO-8601 UTC).
  - `last_success_at` string, nullable, required: Last successful delivery instant, or null.
  - `last_failure_at` string, nullable, required: Last failed delivery instant, or null.
  - `disabled_at` string, nullable, required: When the subscription was disabled, or null.
  - `disabled_reason` string, nullable, required: Why it was disabled (e.g. delivery_failures), or null.

## Other responses

- `400`: A query parameter or request body was malformed (invalid_request).
- `401`: Missing, malformed, or wrong-kind credential (unauthorized / token_revoked / account_deleted).
- `403`: The credential lacks the required scope, or the workspace cannot access paid features (forbidden / pro_plan_required).
- `404`: The resource does not exist or is not readable by the caller (not_found).
- `429`: Rate limit exceeded (rate_limited); see the Retry-After header.
- `500`: An unexpected server error occurred (internal_error).

---

[API](https://skmtc.dev/usebubbles/apis/bubbles-public-api.md) - [All operations](https://skmtc.dev/usebubbles/apis/bubbles-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/usebubbles/apis/bubbles-public-api/revisions/31570f5d4b05?raw)
