---
title: "Update a webhook"
method: PATCH
path: "/api/webhooks/{id}"
tags: ["Webhooks"]
---

# Update a webhook

`PATCH /api/webhooks/{id}`

## Request

- Base URL: `https://www.flyn.to`
- URL: `https://www.flyn.to/api/webhooks/{id}`
- Auth: HTTP bearer

Changes the url, events and/or status of a webhook the caller created. Setting status `active` resets failureCount to 0, which is how a webhook disabled after 10 counted failures is switched back on.

**Auth:** API key (`Bearer flyn_sk_live_...`), or the signed-in dashboard session cookie when no API key header is sent. MCP OAuth access tokens are not accepted here and get 401.

**Plan:** every plan. Only the creator can edit, whatever their team role.

**Rate limit:** 10 requests per 60 s per client IP, fixed window, in memory per server instance, checked before authentication.

A webhook that does not exist, was created by someone else, or has a malformed id returns 500, not 404. An invalid JSON body also returns 500.

## Request body

- WebhookUpdateRequest: All fields optional. An empty body succeeds and changes nothing but the update time.
  - `url` string: http or https, not a private address.
  - `events` WebhookEventName[]: Replaces the subscription. Every name must be known, else 400 "Invalid events: ...".
  - `status` 'active' | 'inactive': `active` also resets failureCount to 0.

## Response `200`

Updated. API-key callers see the secret as its first 8 characters followed by "...".

- WebhookEnvelope
  - `webhook` Webhook, required
    - `id` string, uuid, required
    - `url` string, required: Delivery endpoint.
    - `events` string[], required: Subscribed event names, as stored.
    - `secret` string, nullable, required: Signing secret, `whsec_` + 48 hex. Always in full in the create response. Afterwards API-key callers see only a masked prefix (first 8 characters); the creator's own dashboard session sees it in full.
    - `status` 'active' | 'inactive', required: A webhook becomes inactive after 10 counted delivery failures in a row.
    - `createdAt` integer, required: Unix time in milliseconds.
    - `lastTriggeredAt` integer, nullable: Unix time in milliseconds of the last successful delivery. Absent from the create response.
    - `failureCount` integer, required: Counted failures since the last success (non-2xx answers, and skips of a URL whose host resolves to a private address or fails DNS resolution; timeouts and connection errors are not counted).

## Other responses

- `400`: Messages: "Only HTTP/HTTPS URLs allowed", "Webhook URL must be a public address", "Invalid URL", "Events must be a non-empty array", "Invalid events: <names>", "Status must be active or inactive".
- `401`: No valid API key and no dashboard session. Messages: "Invalid or revoked API key", "API key has expired", "Unauthorized. Sign in to the dashboard, or pass a Bearer API key in the Authorization header.", or "Unauthorized" when the session lookup itself fails. An MCP OAuth token lands here too.
- `403`: The account is suspended.
- `429`: More than 10 requests in the window. Counted per client IP. Retry-After gives the seconds until the window resets.
- `500`: Not found, not created by the caller, malformed id, invalid JSON, or a database error.

---

[API](https://skmtc.dev/flyn/apis/flyn-api.md) · [All operations](https://skmtc.dev/flyn/apis/flyn-api/llms.txt) · [OpenAPI document](https://skmtc.dev/flyn/apis/flyn-api/revisions/977962a98ccb?raw)
