# Webhooks endpoints

> Webhook endpoints, their signing secrets and the delivery log. Every operation with parameters, body, responses, errors and examples.

Source: https://developers.processcart.com/reference/webhooks

Webhook endpoints, their signing secrets and the delivery log.

Base URL `https://app.processcart.com/api/v1`. Every operation below is also in the [OpenAPI document](https://developers.processcart.com/openapi.json) and the [interactive reference](https://developers.processcart.com/reference).

| Operation | Method and path | Scope |
| --- | --- | --- |
| [List webhooks](#listWebhooks) | <code class="pc-docs-wrap">GET /v1<wbr>/webhooks</code> | Scope `webhooks:manage` |
| [Create a webhook](#createWebhook) | <code class="pc-docs-wrap">POST /v1<wbr>/webhooks</code> | Scope `webhooks:manage` |
| [Get a webhook](#getWebhook) | <code class="pc-docs-wrap">GET /v1<wbr>/webhooks<wbr>/{id}</code> | Scope `webhooks:manage` |
| [Update a webhook](#updateWebhook) | <code class="pc-docs-wrap">PATCH /v1<wbr>/webhooks<wbr>/{id}</code> | Scope `webhooks:manage` |
| [Delete a webhook](#deleteWebhook) | <code class="pc-docs-wrap">DELETE /v1<wbr>/webhooks<wbr>/{id}</code> | Scope `webhooks:manage` |
| [Enable a webhook](#enableWebhook) | <code class="pc-docs-wrap">POST /v1<wbr>/webhooks<wbr>/{id}<wbr>/enable</code> | Scope `webhooks:manage` |
| [Disable a webhook](#disableWebhook) | <code class="pc-docs-wrap">POST /v1<wbr>/webhooks<wbr>/{id}<wbr>/disable</code> | Scope `webhooks:manage` |
| [Rotate a webhook's signing secret](#rotateWebhookSecret) | <code class="pc-docs-wrap">POST /v1<wbr>/webhooks<wbr>/{id}<wbr>/rotate-secret</code> | Scope `webhooks:manage` |
| [Send a test event](#testWebhook) | <code class="pc-docs-wrap">POST /v1<wbr>/webhooks<wbr>/{id}<wbr>/test</code> | Scope `webhooks:manage` |
| [List a webhook's deliveries](#listWebhookDeliveries) | <code class="pc-docs-wrap">GET /v1<wbr>/webhooks<wbr>/{id}<wbr>/deliveries</code> | Scope `webhooks:manage` |
| [Get a delivery](#getWebhookDelivery) | <code class="pc-docs-wrap">GET /v1<wbr>/webhooks<wbr>/{id}<wbr>/deliveries<wbr>/{deliveryId}</code> | Scope `webhooks:manage` |
| [Send a delivery again](#redeliverWebhookDelivery) | <code class="pc-docs-wrap">POST /v1<wbr>/webhooks<wbr>/{id}<wbr>/deliveries<wbr>/{deliveryId}<wbr>/redeliver</code> | Scope `webhooks:manage` |

## GET /v1/webhooks
**List webhooks.** Scope `webhooks:manage` · the key's allowlist narrows the rows (never a 403 — rows outside it are absent) · paginated (`{ data, nextCursor, hasMore }`). Operation id `listWebhooks` · [open in the API reference](https://developers.processcart.com/reference#tag/webhooks/GET/v1/webhooks).

Lists the workspace's webhook endpoints, newest first (no secrets). `updatedSince` turns the list into an incremental sync ordered by `updatedAt` ascending (inclusive). Keys restricted to folders cannot use the webhook operations (403 `not_allowed_for_key`); keys restricted to workflows manage only webhooks whose `workflowIds` is a non-empty subset of their allowlist, and see only deliveries about those workflows (plus test events).

**Query parameters** (an unknown parameter is a 422 `validation_failed` with `errors[].code = "unknown_parameter"`)

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `updatedSince` | string (date-time) | no | Incremental sync: only items whose `updatedAt` is at or after this instant (inclusive), ordered by `updatedAt` ascending; an explicit conflicting `sort` / `order` is a 422. Overlap by a minute and dedupe: a Run by `(id, revision)`, any other item (workflow, view, webhook, schedule, automation rule) by `(id, updatedAt)` — a higher `revision` or a later `updatedAt` replaces the copy you hold, an equal one is unchanged. |
| `limit` | integer | no |  |
| `cursor` | string | no | The `nextCursor` of the previous page. Opaque, and bound to the query that produced it — a cursor from a different filter or sort is a 422. |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| 200 | OK. | [WebhookList](https://developers.processcart.com/reference/schemas#webhooklist) |
| 401 | No usable credential. `unauthorized` — Authentication required; `invalid_api_key` — Invalid API key; `key_revoked` — API key revoked. | [Problem](https://developers.processcart.com/errors) |
| 403 | `insufficient_scope` — Insufficient scope; `not_allowed_for_key` — Not allowed for this key. | [Problem](https://developers.processcart.com/errors) |
| 405 | The verb is not supported on this path. `method_not_allowed` — Method not allowed. | [Problem](https://developers.processcart.com/errors) |
| 422 | `validation_failed` — Validation failed. | [Problem](https://developers.processcart.com/errors) |
| 429 | `rate_limited` — Too many requests. | [Problem](https://developers.processcart.com/errors) |
| 500 | `internal_error` — Internal error. | [Problem](https://developers.processcart.com/errors) |
| 503 | `unavailable` — Service unavailable. | [Problem](https://developers.processcart.com/errors) |

**Errors** (every code this operation can answer; see [Errors](https://developers.processcart.com/errors))

- 401 [`invalid_api_key`](https://developers.processcart.com/errors#invalid_api_key) — Invalid API key
- 401 [`key_revoked`](https://developers.processcart.com/errors#key_revoked) — API key revoked
- 401 [`unauthorized`](https://developers.processcart.com/errors#unauthorized) — Authentication required
- 403 [`insufficient_scope`](https://developers.processcart.com/errors#insufficient_scope) — Insufficient scope
- 403 [`not_allowed_for_key`](https://developers.processcart.com/errors#not_allowed_for_key) — Not allowed for this key
- 405 [`method_not_allowed`](https://developers.processcart.com/errors#method_not_allowed) — Method not allowed
- 422 [`validation_failed`](https://developers.processcart.com/errors#validation_failed) — Validation failed
- 429 [`rate_limited`](https://developers.processcart.com/errors#rate_limited) — Too many requests
- 500 [`internal_error`](https://developers.processcart.com/errors#internal_error) — Internal error
- 503 [`unavailable`](https://developers.processcart.com/errors#unavailable) — Service unavailable

**Example response** (200)

```json
{
  "data": [
    {
      "id": "2b64ebdd-e0ba-4d01-aca7-914b36d905aa",
      "url": "https://hooks.example.com/processcart",
      "description": "Everything",
      "events": [
        "*"
      ],
      "workflowIds": null,
      "filters": {},
      "enabled": true,
      "disabledReason": null,
      "disabledAt": null,
      "consecutiveFailures": 0,
      "lastDeliveryAt": null,
      "createdAt": "2026-10-11T05:28:25.162Z",
      "createdBy": null,
      "updatedAt": "2026-10-11T05:28:25.162Z"
    }
  ],
  "nextCursor": null,
  "hasMore": false
}
```


## POST /v1/webhooks
**Create a webhook.** Scope `webhooks:manage` · accepts `Idempotency-Key`. Operation id `createWebhook` · [open in the API reference](https://developers.processcart.com/reference#tag/webhooks/POST/v1/webhooks).

Subscribes an https endpoint to events (`*` = everything but the opt-in types), optionally narrowed to some workflows and, for `field.updated`, to some field keys. The response carries the Standard Webhooks signing secret ONCE — store it; rotate to get a new one. The URL is checked against the SSRF policy (public https only). Keys restricted to folders cannot use the webhook operations (403 `not_allowed_for_key`); keys restricted to workflows manage only webhooks whose `workflowIds` is a non-empty subset of their allowlist, and see only deliveries about those workflows (plus test events).

**Request headers**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Idempotency-Key` | string | no | Makes the request safe to retry: a second request with the same key and a byte-identical body (and the same `Expected-Revision`) replays the stored response (`Idempotent-Replayed: true`); a different body with the same key is refused (422 `idempotency_key_reused`) and no second resource is created. Keys are stored per workspace for 24 hours and replayed only to the API key that made the request (or the key one rotation away from it); another API key sending the same value is refused (422 `idempotency_key_reused`), so prefix keys per integration. 409, 429 and 5xx answers are never stored. |

**Request body** — `application/json`, [WebhookConfig](https://developers.processcart.com/reference/schemas#webhookconfig)

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | string | yes |  |
| `description` | string | no |  |
| `events` | [EventType](https://developers.processcart.com/reference/schemas#eventtype) \\| `"*"`[] | yes |  |
| `workflowIds` | [Uuid](https://developers.processcart.com/reference/schemas#uuid)[] \\| null | no |  |
| `filters` | object | no |  |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| 201 | Created. `Location` names the new resource. | [WebhookWithSecret](https://developers.processcart.com/reference/schemas#webhookwithsecret) |
| 401 | No usable credential. `unauthorized` — Authentication required; `invalid_api_key` — Invalid API key; `key_revoked` — API key revoked. | [Problem](https://developers.processcart.com/errors) |
| 403 | `insufficient_scope` — Insufficient scope; `not_allowed_for_key` — Not allowed for this key; `read_only_key` — Read-only key. | [Problem](https://developers.processcart.com/errors) |
| 405 | The verb is not supported on this path. `method_not_allowed` — Method not allowed. | [Problem](https://developers.processcart.com/errors) |
| 409 | `idempotency_in_progress` — Request in progress. | [Problem](https://developers.processcart.com/errors) |
| 413 | `payload_too_large` — Payload too large. | [Problem](https://developers.processcart.com/errors) |
| 415 | `unsupported_media_type` — Unsupported media type. | [Problem](https://developers.processcart.com/errors) |
| 422 | `idempotency_key_reused` — Idempotency key reused; `validation_failed` — Validation failed. | [Problem](https://developers.processcart.com/errors) |
| 429 | `rate_limited` — Too many requests. | [Problem](https://developers.processcart.com/errors) |
| 500 | `internal_error` — Internal error. | [Problem](https://developers.processcart.com/errors) |
| 503 | `unavailable` — Service unavailable. | [Problem](https://developers.processcart.com/errors) |

**Errors** (every code this operation can answer; see [Errors](https://developers.processcart.com/errors))

- 401 [`invalid_api_key`](https://developers.processcart.com/errors#invalid_api_key) — Invalid API key
- 401 [`key_revoked`](https://developers.processcart.com/errors#key_revoked) — API key revoked
- 401 [`unauthorized`](https://developers.processcart.com/errors#unauthorized) — Authentication required
- 403 [`insufficient_scope`](https://developers.processcart.com/errors#insufficient_scope) — Insufficient scope
- 403 [`not_allowed_for_key`](https://developers.processcart.com/errors#not_allowed_for_key) — Not allowed for this key
- 403 [`read_only_key`](https://developers.processcart.com/errors#read_only_key) — Read-only key
- 405 [`method_not_allowed`](https://developers.processcart.com/errors#method_not_allowed) — Method not allowed
- 409 [`idempotency_in_progress`](https://developers.processcart.com/errors#idempotency_in_progress) — Request in progress
- 413 [`payload_too_large`](https://developers.processcart.com/errors#payload_too_large) — Payload too large
- 415 [`unsupported_media_type`](https://developers.processcart.com/errors#unsupported_media_type) — Unsupported media type
- 422 [`idempotency_key_reused`](https://developers.processcart.com/errors#idempotency_key_reused) — Idempotency key reused
- 422 [`validation_failed`](https://developers.processcart.com/errors#validation_failed) — Validation failed
- 429 [`rate_limited`](https://developers.processcart.com/errors#rate_limited) — Too many requests
- 500 [`internal_error`](https://developers.processcart.com/errors#internal_error) — Internal error
- 503 [`unavailable`](https://developers.processcart.com/errors#unavailable) — Service unavailable

**Example request**

```json
{
  "url": "https://hooks.example.com/processcart",
  "description": "Everything",
  "events": [
    "*"
  ]
}
```

**Example response** (201)

```json
{
  "id": "2b64ebdd-e0ba-4d01-aca7-914b36d905aa",
  "url": "https://hooks.example.com/processcart",
  "description": "Everything",
  "events": [
    "*"
  ],
  "workflowIds": null,
  "filters": {},
  "enabled": true,
  "disabledReason": null,
  "disabledAt": null,
  "consecutiveFailures": 0,
  "lastDeliveryAt": null,
  "createdAt": "2026-10-11T05:28:25.162Z",
  "createdBy": null,
  "updatedAt": "2026-10-11T05:28:25.162Z",
  "secret": "whsec_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE"
}
```


## GET /v1/webhooks/{id}
**Get a webhook.** Scope `webhooks:manage`. Operation id `getWebhook` · [open in the API reference](https://developers.processcart.com/reference#tag/webhooks/GET/v1/webhooks/{id}).

Returns one webhook endpoint with its subscription, filters, enabled state, failure counter and last delivery time — never the secret.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string (uuid) | yes |  |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| 200 | OK. | [Webhook](https://developers.processcart.com/reference/schemas#webhook) |
| 401 | No usable credential. `unauthorized` — Authentication required; `invalid_api_key` — Invalid API key; `key_revoked` — API key revoked. | [Problem](https://developers.processcart.com/errors) |
| 403 | `insufficient_scope` — Insufficient scope; `not_allowed_for_key` — Not allowed for this key. | [Problem](https://developers.processcart.com/errors) |
| 404 | `not_found` — Not found. | [Problem](https://developers.processcart.com/errors) |
| 405 | The verb is not supported on this path. `method_not_allowed` — Method not allowed. | [Problem](https://developers.processcart.com/errors) |
| 422 | `validation_failed` — Validation failed. | [Problem](https://developers.processcart.com/errors) |
| 429 | `rate_limited` — Too many requests. | [Problem](https://developers.processcart.com/errors) |
| 500 | `internal_error` — Internal error. | [Problem](https://developers.processcart.com/errors) |
| 503 | `unavailable` — Service unavailable. | [Problem](https://developers.processcart.com/errors) |

**Errors** (every code this operation can answer; see [Errors](https://developers.processcart.com/errors))

- 401 [`invalid_api_key`](https://developers.processcart.com/errors#invalid_api_key) — Invalid API key
- 401 [`key_revoked`](https://developers.processcart.com/errors#key_revoked) — API key revoked
- 401 [`unauthorized`](https://developers.processcart.com/errors#unauthorized) — Authentication required
- 403 [`insufficient_scope`](https://developers.processcart.com/errors#insufficient_scope) — Insufficient scope
- 403 [`not_allowed_for_key`](https://developers.processcart.com/errors#not_allowed_for_key) — Not allowed for this key
- 404 [`not_found`](https://developers.processcart.com/errors#not_found) — Not found
- 405 [`method_not_allowed`](https://developers.processcart.com/errors#method_not_allowed) — Method not allowed
- 422 [`validation_failed`](https://developers.processcart.com/errors#validation_failed) — Validation failed
- 429 [`rate_limited`](https://developers.processcart.com/errors#rate_limited) — Too many requests
- 500 [`internal_error`](https://developers.processcart.com/errors#internal_error) — Internal error
- 503 [`unavailable`](https://developers.processcart.com/errors#unavailable) — Service unavailable

**Example response** (200)

```json
{
  "id": "2b64ebdd-e0ba-4d01-aca7-914b36d905aa",
  "url": "https://hooks.example.com/processcart",
  "description": "Everything",
  "events": [
    "*"
  ],
  "workflowIds": null,
  "filters": {},
  "enabled": true,
  "disabledReason": null,
  "disabledAt": null,
  "consecutiveFailures": 0,
  "lastDeliveryAt": null,
  "createdAt": "2026-10-11T05:28:25.162Z",
  "createdBy": null,
  "updatedAt": "2026-10-11T05:28:25.162Z"
}
```


## PATCH /v1/webhooks/{id}
**Update a webhook.** Scope `webhooks:manage` · accepts `Idempotency-Key`. Operation id `updateWebhook` · [open in the API reference](https://developers.processcart.com/reference#tag/webhooks/PATCH/v1/webhooks/{id}).

Changes any subset of the configuration: `url` (re-checked against the SSRF policy), `description`, `events`, `workflowIds` (`null` clears the filter; omit the key to keep it) and `filters`. `enabled` is not part of the configuration — use the enable and disable operations. Audited.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string (uuid) | yes |  |

**Request headers**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Idempotency-Key` | string | no | Makes the request safe to retry: a second request with the same key and a byte-identical body (and the same `Expected-Revision`) replays the stored response (`Idempotent-Replayed: true`); a different body with the same key is refused (422 `idempotency_key_reused`) and no second resource is created. Keys are stored per workspace for 24 hours and replayed only to the API key that made the request (or the key one rotation away from it); another API key sending the same value is refused (422 `idempotency_key_reused`), so prefix keys per integration. 409, 429 and 5xx answers are never stored. |

**Request body** — `application/json`, [WebhookPatch](https://developers.processcart.com/reference/schemas#webhookpatch)

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | string | no |  |
| `description` | string | no |  |
| `events` | [EventType](https://developers.processcart.com/reference/schemas#eventtype) \\| `"*"`[] | no |  |
| `workflowIds` | [Uuid](https://developers.processcart.com/reference/schemas#uuid)[] \\| null | no |  |
| `filters` | object | no |  |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| 200 | OK. | [Webhook](https://developers.processcart.com/reference/schemas#webhook) |
| 401 | No usable credential. `unauthorized` — Authentication required; `invalid_api_key` — Invalid API key; `key_revoked` — API key revoked. | [Problem](https://developers.processcart.com/errors) |
| 403 | `insufficient_scope` — Insufficient scope; `not_allowed_for_key` — Not allowed for this key; `read_only_key` — Read-only key. | [Problem](https://developers.processcart.com/errors) |
| 404 | `not_found` — Not found. | [Problem](https://developers.processcart.com/errors) |
| 405 | The verb is not supported on this path. `method_not_allowed` — Method not allowed. | [Problem](https://developers.processcart.com/errors) |
| 409 | `idempotency_in_progress` — Request in progress. | [Problem](https://developers.processcart.com/errors) |
| 413 | `payload_too_large` — Payload too large. | [Problem](https://developers.processcart.com/errors) |
| 415 | `unsupported_media_type` — Unsupported media type. | [Problem](https://developers.processcart.com/errors) |
| 422 | `idempotency_key_reused` — Idempotency key reused; `validation_failed` — Validation failed. | [Problem](https://developers.processcart.com/errors) |
| 429 | `rate_limited` — Too many requests. | [Problem](https://developers.processcart.com/errors) |
| 500 | `internal_error` — Internal error. | [Problem](https://developers.processcart.com/errors) |
| 503 | `unavailable` — Service unavailable. | [Problem](https://developers.processcart.com/errors) |

**Errors** (every code this operation can answer; see [Errors](https://developers.processcart.com/errors))

- 401 [`invalid_api_key`](https://developers.processcart.com/errors#invalid_api_key) — Invalid API key
- 401 [`key_revoked`](https://developers.processcart.com/errors#key_revoked) — API key revoked
- 401 [`unauthorized`](https://developers.processcart.com/errors#unauthorized) — Authentication required
- 403 [`insufficient_scope`](https://developers.processcart.com/errors#insufficient_scope) — Insufficient scope
- 403 [`not_allowed_for_key`](https://developers.processcart.com/errors#not_allowed_for_key) — Not allowed for this key
- 403 [`read_only_key`](https://developers.processcart.com/errors#read_only_key) — Read-only key
- 404 [`not_found`](https://developers.processcart.com/errors#not_found) — Not found
- 405 [`method_not_allowed`](https://developers.processcart.com/errors#method_not_allowed) — Method not allowed
- 409 [`idempotency_in_progress`](https://developers.processcart.com/errors#idempotency_in_progress) — Request in progress
- 413 [`payload_too_large`](https://developers.processcart.com/errors#payload_too_large) — Payload too large
- 415 [`unsupported_media_type`](https://developers.processcart.com/errors#unsupported_media_type) — Unsupported media type
- 422 [`idempotency_key_reused`](https://developers.processcart.com/errors#idempotency_key_reused) — Idempotency key reused
- 422 [`validation_failed`](https://developers.processcart.com/errors#validation_failed) — Validation failed
- 429 [`rate_limited`](https://developers.processcart.com/errors#rate_limited) — Too many requests
- 500 [`internal_error`](https://developers.processcart.com/errors#internal_error) — Internal error
- 503 [`unavailable`](https://developers.processcart.com/errors#unavailable) — Service unavailable

**Example request**

```json
{
  "description": "Renamed",
  "events": [
    "run.created",
    "run.completed"
  ]
}
```

**Example response** (200)

```json
{
  "id": "2b64ebdd-e0ba-4d01-aca7-914b36d905aa",
  "url": "https://hooks.example.com/processcart",
  "description": "Renamed",
  "events": [
    "run.created",
    "run.completed"
  ],
  "workflowIds": null,
  "filters": {},
  "enabled": true,
  "disabledReason": null,
  "disabledAt": null,
  "consecutiveFailures": 0,
  "lastDeliveryAt": "2026-10-11T05:28:29.806Z",
  "createdAt": "2026-10-11T05:28:25.162Z",
  "createdBy": null,
  "updatedAt": "2026-10-11T05:28:30.342Z"
}
```


## DELETE /v1/webhooks/{id}
**Delete a webhook.** Scope `webhooks:manage` · accepts `Idempotency-Key`. Operation id `deleteWebhook` · [open in the API reference](https://developers.processcart.com/reference#tag/webhooks/DELETE/v1/webhooks/{id}).

Removes the endpoint with its secret and delivery log. Pending deliveries are dropped; nothing is sent to the endpoint. Audited.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string (uuid) | yes |  |

**Request headers**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Idempotency-Key` | string | no | Makes the request safe to retry: a second request with the same key and a byte-identical body (and the same `Expected-Revision`) replays the stored response (`Idempotent-Replayed: true`); a different body with the same key is refused (422 `idempotency_key_reused`) and no second resource is created. Keys are stored per workspace for 24 hours and replayed only to the API key that made the request (or the key one rotation away from it); another API key sending the same value is refused (422 `idempotency_key_reused`), so prefix keys per integration. 409, 429 and 5xx answers are never stored. |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| 204 | Done; no body. | — |
| 401 | No usable credential. `unauthorized` — Authentication required; `invalid_api_key` — Invalid API key; `key_revoked` — API key revoked. | [Problem](https://developers.processcart.com/errors) |
| 403 | `insufficient_scope` — Insufficient scope; `not_allowed_for_key` — Not allowed for this key; `read_only_key` — Read-only key. | [Problem](https://developers.processcart.com/errors) |
| 404 | `not_found` — Not found. | [Problem](https://developers.processcart.com/errors) |
| 405 | The verb is not supported on this path. `method_not_allowed` — Method not allowed. | [Problem](https://developers.processcart.com/errors) |
| 409 | `idempotency_in_progress` — Request in progress. | [Problem](https://developers.processcart.com/errors) |
| 422 | `idempotency_key_reused` — Idempotency key reused; `validation_failed` — Validation failed. | [Problem](https://developers.processcart.com/errors) |
| 429 | `rate_limited` — Too many requests. | [Problem](https://developers.processcart.com/errors) |
| 500 | `internal_error` — Internal error. | [Problem](https://developers.processcart.com/errors) |
| 503 | `unavailable` — Service unavailable. | [Problem](https://developers.processcart.com/errors) |

**Errors** (every code this operation can answer; see [Errors](https://developers.processcart.com/errors))

- 401 [`invalid_api_key`](https://developers.processcart.com/errors#invalid_api_key) — Invalid API key
- 401 [`key_revoked`](https://developers.processcart.com/errors#key_revoked) — API key revoked
- 401 [`unauthorized`](https://developers.processcart.com/errors#unauthorized) — Authentication required
- 403 [`insufficient_scope`](https://developers.processcart.com/errors#insufficient_scope) — Insufficient scope
- 403 [`not_allowed_for_key`](https://developers.processcart.com/errors#not_allowed_for_key) — Not allowed for this key
- 403 [`read_only_key`](https://developers.processcart.com/errors#read_only_key) — Read-only key
- 404 [`not_found`](https://developers.processcart.com/errors#not_found) — Not found
- 405 [`method_not_allowed`](https://developers.processcart.com/errors#method_not_allowed) — Method not allowed
- 409 [`idempotency_in_progress`](https://developers.processcart.com/errors#idempotency_in_progress) — Request in progress
- 422 [`idempotency_key_reused`](https://developers.processcart.com/errors#idempotency_key_reused) — Idempotency key reused
- 422 [`validation_failed`](https://developers.processcart.com/errors#validation_failed) — Validation failed
- 429 [`rate_limited`](https://developers.processcart.com/errors#rate_limited) — Too many requests
- 500 [`internal_error`](https://developers.processcart.com/errors#internal_error) — Internal error
- 503 [`unavailable`](https://developers.processcart.com/errors#unavailable) — Service unavailable


## POST /v1/webhooks/{id}/enable
**Enable a webhook.** Scope `webhooks:manage` · accepts `Idempotency-Key`. Operation id `enableWebhook` · [open in the API reference](https://developers.processcart.com/reference#tag/webhooks/POST/v1/webhooks/{id}/enable).

Turns deliveries back on and resets the consecutive-failure counter — also the way to bring back an endpoint that was disabled automatically (after repeated failures or a 410). Enabling an enabled webhook answers 200 unchanged.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string (uuid) | yes |  |

**Request headers**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Idempotency-Key` | string | no | Makes the request safe to retry: a second request with the same key and a byte-identical body (and the same `Expected-Revision`) replays the stored response (`Idempotent-Replayed: true`); a different body with the same key is refused (422 `idempotency_key_reused`) and no second resource is created. Keys are stored per workspace for 24 hours and replayed only to the API key that made the request (or the key one rotation away from it); another API key sending the same value is refused (422 `idempotency_key_reused`), so prefix keys per integration. 409, 429 and 5xx answers are never stored. |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| 200 | OK. | [Webhook](https://developers.processcart.com/reference/schemas#webhook) |
| 401 | No usable credential. `unauthorized` — Authentication required; `invalid_api_key` — Invalid API key; `key_revoked` — API key revoked. | [Problem](https://developers.processcart.com/errors) |
| 403 | `insufficient_scope` — Insufficient scope; `not_allowed_for_key` — Not allowed for this key; `read_only_key` — Read-only key. | [Problem](https://developers.processcart.com/errors) |
| 404 | `not_found` — Not found. | [Problem](https://developers.processcart.com/errors) |
| 405 | The verb is not supported on this path. `method_not_allowed` — Method not allowed. | [Problem](https://developers.processcart.com/errors) |
| 409 | `idempotency_in_progress` — Request in progress. | [Problem](https://developers.processcart.com/errors) |
| 422 | `idempotency_key_reused` — Idempotency key reused; `validation_failed` — Validation failed. | [Problem](https://developers.processcart.com/errors) |
| 429 | `rate_limited` — Too many requests. | [Problem](https://developers.processcart.com/errors) |
| 500 | `internal_error` — Internal error. | [Problem](https://developers.processcart.com/errors) |
| 503 | `unavailable` — Service unavailable. | [Problem](https://developers.processcart.com/errors) |

**Errors** (every code this operation can answer; see [Errors](https://developers.processcart.com/errors))

- 401 [`invalid_api_key`](https://developers.processcart.com/errors#invalid_api_key) — Invalid API key
- 401 [`key_revoked`](https://developers.processcart.com/errors#key_revoked) — API key revoked
- 401 [`unauthorized`](https://developers.processcart.com/errors#unauthorized) — Authentication required
- 403 [`insufficient_scope`](https://developers.processcart.com/errors#insufficient_scope) — Insufficient scope
- 403 [`not_allowed_for_key`](https://developers.processcart.com/errors#not_allowed_for_key) — Not allowed for this key
- 403 [`read_only_key`](https://developers.processcart.com/errors#read_only_key) — Read-only key
- 404 [`not_found`](https://developers.processcart.com/errors#not_found) — Not found
- 405 [`method_not_allowed`](https://developers.processcart.com/errors#method_not_allowed) — Method not allowed
- 409 [`idempotency_in_progress`](https://developers.processcart.com/errors#idempotency_in_progress) — Request in progress
- 422 [`idempotency_key_reused`](https://developers.processcart.com/errors#idempotency_key_reused) — Idempotency key reused
- 422 [`validation_failed`](https://developers.processcart.com/errors#validation_failed) — Validation failed
- 429 [`rate_limited`](https://developers.processcart.com/errors#rate_limited) — Too many requests
- 500 [`internal_error`](https://developers.processcart.com/errors#internal_error) — Internal error
- 503 [`unavailable`](https://developers.processcart.com/errors#unavailable) — Service unavailable

**Example response** (200)

```json
{
  "id": "2b64ebdd-e0ba-4d01-aca7-914b36d905aa",
  "url": "https://hooks.example.com/processcart",
  "description": "Everything",
  "events": [
    "*"
  ],
  "workflowIds": null,
  "filters": {},
  "enabled": true,
  "disabledReason": null,
  "disabledAt": null,
  "consecutiveFailures": 0,
  "lastDeliveryAt": "2026-10-11T05:28:27.885Z",
  "createdAt": "2026-10-11T05:28:25.162Z",
  "createdBy": null,
  "updatedAt": "2026-10-11T05:28:28.995Z"
}
```


## POST /v1/webhooks/{id}/disable
**Disable a webhook.** Scope `webhooks:manage` · accepts `Idempotency-Key`. Operation id `disableWebhook` · [open in the API reference](https://developers.processcart.com/reference#tag/webhooks/POST/v1/webhooks/{id}/disable).

Stops deliveries (reason `manual`). Events that happen while it is disabled are not queued for it. Disabling a disabled webhook answers 200 unchanged.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string (uuid) | yes |  |

**Request headers**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Idempotency-Key` | string | no | Makes the request safe to retry: a second request with the same key and a byte-identical body (and the same `Expected-Revision`) replays the stored response (`Idempotent-Replayed: true`); a different body with the same key is refused (422 `idempotency_key_reused`) and no second resource is created. Keys are stored per workspace for 24 hours and replayed only to the API key that made the request (or the key one rotation away from it); another API key sending the same value is refused (422 `idempotency_key_reused`), so prefix keys per integration. 409, 429 and 5xx answers are never stored. |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| 200 | OK. | [Webhook](https://developers.processcart.com/reference/schemas#webhook) |
| 401 | No usable credential. `unauthorized` — Authentication required; `invalid_api_key` — Invalid API key; `key_revoked` — API key revoked. | [Problem](https://developers.processcart.com/errors) |
| 403 | `insufficient_scope` — Insufficient scope; `not_allowed_for_key` — Not allowed for this key; `read_only_key` — Read-only key. | [Problem](https://developers.processcart.com/errors) |
| 404 | `not_found` — Not found. | [Problem](https://developers.processcart.com/errors) |
| 405 | The verb is not supported on this path. `method_not_allowed` — Method not allowed. | [Problem](https://developers.processcart.com/errors) |
| 409 | `idempotency_in_progress` — Request in progress. | [Problem](https://developers.processcart.com/errors) |
| 422 | `idempotency_key_reused` — Idempotency key reused; `validation_failed` — Validation failed. | [Problem](https://developers.processcart.com/errors) |
| 429 | `rate_limited` — Too many requests. | [Problem](https://developers.processcart.com/errors) |
| 500 | `internal_error` — Internal error. | [Problem](https://developers.processcart.com/errors) |
| 503 | `unavailable` — Service unavailable. | [Problem](https://developers.processcart.com/errors) |

**Errors** (every code this operation can answer; see [Errors](https://developers.processcart.com/errors))

- 401 [`invalid_api_key`](https://developers.processcart.com/errors#invalid_api_key) — Invalid API key
- 401 [`key_revoked`](https://developers.processcart.com/errors#key_revoked) — API key revoked
- 401 [`unauthorized`](https://developers.processcart.com/errors#unauthorized) — Authentication required
- 403 [`insufficient_scope`](https://developers.processcart.com/errors#insufficient_scope) — Insufficient scope
- 403 [`not_allowed_for_key`](https://developers.processcart.com/errors#not_allowed_for_key) — Not allowed for this key
- 403 [`read_only_key`](https://developers.processcart.com/errors#read_only_key) — Read-only key
- 404 [`not_found`](https://developers.processcart.com/errors#not_found) — Not found
- 405 [`method_not_allowed`](https://developers.processcart.com/errors#method_not_allowed) — Method not allowed
- 409 [`idempotency_in_progress`](https://developers.processcart.com/errors#idempotency_in_progress) — Request in progress
- 422 [`idempotency_key_reused`](https://developers.processcart.com/errors#idempotency_key_reused) — Idempotency key reused
- 422 [`validation_failed`](https://developers.processcart.com/errors#validation_failed) — Validation failed
- 429 [`rate_limited`](https://developers.processcart.com/errors#rate_limited) — Too many requests
- 500 [`internal_error`](https://developers.processcart.com/errors#internal_error) — Internal error
- 503 [`unavailable`](https://developers.processcart.com/errors#unavailable) — Service unavailable

**Example response** (200)

```json
{
  "id": "2b64ebdd-e0ba-4d01-aca7-914b36d905aa",
  "url": "https://hooks.example.com/processcart",
  "description": "Everything",
  "events": [
    "*"
  ],
  "workflowIds": null,
  "filters": {},
  "enabled": false,
  "disabledReason": "manual",
  "disabledAt": "2026-10-11T05:28:28.437Z",
  "consecutiveFailures": 0,
  "lastDeliveryAt": "2026-10-11T05:28:27.885Z",
  "createdAt": "2026-10-11T05:28:25.162Z",
  "createdBy": null,
  "updatedAt": "2026-10-11T05:28:28.437Z"
}
```


## POST /v1/webhooks/{id}/rotate-secret
**Rotate a webhook's signing secret.** Scope `webhooks:manage` · accepts `Idempotency-Key`. Operation id `rotateWebhookSecret` · [open in the API reference](https://developers.processcart.com/reference#tag/webhooks/POST/v1/webhooks/{id}/rotate-secret).

Mints a new signing secret and returns it once. Until `previousExpiresAt` every delivery is signed with both secrets (two entries in `webhook-signature`), so the endpoint can switch without missing a beat. Audited.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string (uuid) | yes |  |

**Request headers**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Idempotency-Key` | string | no | Makes the request safe to retry: a second request with the same key and a byte-identical body (and the same `Expected-Revision`) replays the stored response (`Idempotent-Replayed: true`); a different body with the same key is refused (422 `idempotency_key_reused`) and no second resource is created. Keys are stored per workspace for 24 hours and replayed only to the API key that made the request (or the key one rotation away from it); another API key sending the same value is refused (422 `idempotency_key_reused`), so prefix keys per integration. 409, 429 and 5xx answers are never stored. |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| 200 | OK. | [WebhookSecret](https://developers.processcart.com/reference/schemas#webhooksecret) |
| 401 | No usable credential. `unauthorized` — Authentication required; `invalid_api_key` — Invalid API key; `key_revoked` — API key revoked. | [Problem](https://developers.processcart.com/errors) |
| 403 | `insufficient_scope` — Insufficient scope; `not_allowed_for_key` — Not allowed for this key; `read_only_key` — Read-only key. | [Problem](https://developers.processcart.com/errors) |
| 404 | `not_found` — Not found. | [Problem](https://developers.processcart.com/errors) |
| 405 | The verb is not supported on this path. `method_not_allowed` — Method not allowed. | [Problem](https://developers.processcart.com/errors) |
| 409 | `idempotency_in_progress` — Request in progress. | [Problem](https://developers.processcart.com/errors) |
| 422 | `idempotency_key_reused` — Idempotency key reused; `validation_failed` — Validation failed. | [Problem](https://developers.processcart.com/errors) |
| 429 | `rate_limited` — Too many requests. | [Problem](https://developers.processcart.com/errors) |
| 500 | `internal_error` — Internal error. | [Problem](https://developers.processcart.com/errors) |
| 503 | `unavailable` — Service unavailable. | [Problem](https://developers.processcart.com/errors) |

**Errors** (every code this operation can answer; see [Errors](https://developers.processcart.com/errors))

- 401 [`invalid_api_key`](https://developers.processcart.com/errors#invalid_api_key) — Invalid API key
- 401 [`key_revoked`](https://developers.processcart.com/errors#key_revoked) — API key revoked
- 401 [`unauthorized`](https://developers.processcart.com/errors#unauthorized) — Authentication required
- 403 [`insufficient_scope`](https://developers.processcart.com/errors#insufficient_scope) — Insufficient scope
- 403 [`not_allowed_for_key`](https://developers.processcart.com/errors#not_allowed_for_key) — Not allowed for this key
- 403 [`read_only_key`](https://developers.processcart.com/errors#read_only_key) — Read-only key
- 404 [`not_found`](https://developers.processcart.com/errors#not_found) — Not found
- 405 [`method_not_allowed`](https://developers.processcart.com/errors#method_not_allowed) — Method not allowed
- 409 [`idempotency_in_progress`](https://developers.processcart.com/errors#idempotency_in_progress) — Request in progress
- 422 [`idempotency_key_reused`](https://developers.processcart.com/errors#idempotency_key_reused) — Idempotency key reused
- 422 [`validation_failed`](https://developers.processcart.com/errors#validation_failed) — Validation failed
- 429 [`rate_limited`](https://developers.processcart.com/errors#rate_limited) — Too many requests
- 500 [`internal_error`](https://developers.processcart.com/errors#internal_error) — Internal error
- 503 [`unavailable`](https://developers.processcart.com/errors#unavailable) — Service unavailable

**Example response** (200)

```json
{
  "secret": "whsec_EXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE",
  "previousExpiresAt": "2026-10-12T05:28:29.267Z"
}
```


## POST /v1/webhooks/{id}/test
**Send a test event.** Scope `webhooks:manage` · accepts `Idempotency-Key`. Operation id `testWebhook` · [open in the API reference](https://developers.processcart.com/reference#tag/webhooks/POST/v1/webhooks/{id}/test).

Queues a `webhook.test` delivery to this endpoint and sends it right away (the response does not wait for the endpoint). Read the delivery to see the outcome. A disabled webhook is refused.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string (uuid) | yes |  |

**Request headers**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Idempotency-Key` | string | no | Makes the request safe to retry: a second request with the same key and a byte-identical body (and the same `Expected-Revision`) replays the stored response (`Idempotent-Replayed: true`); a different body with the same key is refused (422 `idempotency_key_reused`) and no second resource is created. Keys are stored per workspace for 24 hours and replayed only to the API key that made the request (or the key one rotation away from it); another API key sending the same value is refused (422 `idempotency_key_reused`), so prefix keys per integration. 409, 429 and 5xx answers are never stored. |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| 202 | Accepted; the work completes asynchronously. | [WebhookQueuedDelivery](https://developers.processcart.com/reference/schemas#webhookqueueddelivery) |
| 401 | No usable credential. `unauthorized` — Authentication required; `invalid_api_key` — Invalid API key; `key_revoked` — API key revoked. | [Problem](https://developers.processcart.com/errors) |
| 403 | `insufficient_scope` — Insufficient scope; `not_allowed_for_key` — Not allowed for this key; `read_only_key` — Read-only key. | [Problem](https://developers.processcart.com/errors) |
| 404 | `not_found` — Not found. | [Problem](https://developers.processcart.com/errors) |
| 405 | The verb is not supported on this path. `method_not_allowed` — Method not allowed. | [Problem](https://developers.processcart.com/errors) |
| 409 | `idempotency_in_progress` — Request in progress; `webhook_disabled` — Webhook disabled. | [Problem](https://developers.processcart.com/errors) |
| 422 | `idempotency_key_reused` — Idempotency key reused; `validation_failed` — Validation failed. | [Problem](https://developers.processcart.com/errors) |
| 429 | `rate_limited` — Too many requests. | [Problem](https://developers.processcart.com/errors) |
| 500 | `internal_error` — Internal error. | [Problem](https://developers.processcart.com/errors) |
| 503 | `unavailable` — Service unavailable. | [Problem](https://developers.processcart.com/errors) |

**Errors** (every code this operation can answer; see [Errors](https://developers.processcart.com/errors))

- 401 [`invalid_api_key`](https://developers.processcart.com/errors#invalid_api_key) — Invalid API key
- 401 [`key_revoked`](https://developers.processcart.com/errors#key_revoked) — API key revoked
- 401 [`unauthorized`](https://developers.processcart.com/errors#unauthorized) — Authentication required
- 403 [`insufficient_scope`](https://developers.processcart.com/errors#insufficient_scope) — Insufficient scope
- 403 [`not_allowed_for_key`](https://developers.processcart.com/errors#not_allowed_for_key) — Not allowed for this key
- 403 [`read_only_key`](https://developers.processcart.com/errors#read_only_key) — Read-only key
- 404 [`not_found`](https://developers.processcart.com/errors#not_found) — Not found
- 405 [`method_not_allowed`](https://developers.processcart.com/errors#method_not_allowed) — Method not allowed
- 409 [`idempotency_in_progress`](https://developers.processcart.com/errors#idempotency_in_progress) — Request in progress
- 409 [`webhook_disabled`](https://developers.processcart.com/errors#webhook_disabled) — Webhook disabled
- 422 [`idempotency_key_reused`](https://developers.processcart.com/errors#idempotency_key_reused) — Idempotency key reused
- 422 [`validation_failed`](https://developers.processcart.com/errors#validation_failed) — Validation failed
- 429 [`rate_limited`](https://developers.processcart.com/errors#rate_limited) — Too many requests
- 500 [`internal_error`](https://developers.processcart.com/errors#internal_error) — Internal error
- 503 [`unavailable`](https://developers.processcart.com/errors#unavailable) — Service unavailable

**Example response** (202)

```json
{
  "delivery": {
    "id": "eb2383ee-da26-48db-aaa3-42e61dc67272",
    "webhookId": "2b64ebdd-e0ba-4d01-aca7-914b36d905aa",
    "attempt": 0
  }
}
```


## GET /v1/webhooks/{id}/deliveries
**List a webhook's deliveries.** Scope `webhooks:manage` · the key's allowlist narrows the rows (never a 403 — rows outside it are absent) · paginated (`{ data, nextCursor, hasMore }`). Operation id `listWebhookDeliveries` · [open in the API reference](https://developers.processcart.com/reference#tag/webhooks/GET/v1/webhooks/{id}/deliveries).

The endpoint's delivery log, newest first, with each delivery's status, attempt count, last response code and next attempt time. Filter by `status`. Deliveries older than the retention window are gone. A key restricted to workflows sees only deliveries about those workflows (and test events).

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string (uuid) | yes |  |

**Query parameters** (an unknown parameter is a 422 `validation_failed` with `errors[].code = "unknown_parameter"`)

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `status` | `"pending"` \\| `"delivered"` \\| `"failed"` \\| `"exhausted"` | no |  |
| `limit` | integer | no |  |
| `cursor` | string | no | The `nextCursor` of the previous page. Opaque, and bound to the query that produced it — a cursor from a different filter or sort is a 422. |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| 200 | OK. | [WebhookDeliveryList](https://developers.processcart.com/reference/schemas#webhookdeliverylist) |
| 401 | No usable credential. `unauthorized` — Authentication required; `invalid_api_key` — Invalid API key; `key_revoked` — API key revoked. | [Problem](https://developers.processcart.com/errors) |
| 403 | `insufficient_scope` — Insufficient scope; `not_allowed_for_key` — Not allowed for this key. | [Problem](https://developers.processcart.com/errors) |
| 404 | `not_found` — Not found. | [Problem](https://developers.processcart.com/errors) |
| 405 | The verb is not supported on this path. `method_not_allowed` — Method not allowed. | [Problem](https://developers.processcart.com/errors) |
| 422 | `validation_failed` — Validation failed. | [Problem](https://developers.processcart.com/errors) |
| 429 | `rate_limited` — Too many requests. | [Problem](https://developers.processcart.com/errors) |
| 500 | `internal_error` — Internal error. | [Problem](https://developers.processcart.com/errors) |
| 503 | `unavailable` — Service unavailable. | [Problem](https://developers.processcart.com/errors) |

**Errors** (every code this operation can answer; see [Errors](https://developers.processcart.com/errors))

- 401 [`invalid_api_key`](https://developers.processcart.com/errors#invalid_api_key) — Invalid API key
- 401 [`key_revoked`](https://developers.processcart.com/errors#key_revoked) — API key revoked
- 401 [`unauthorized`](https://developers.processcart.com/errors#unauthorized) — Authentication required
- 403 [`insufficient_scope`](https://developers.processcart.com/errors#insufficient_scope) — Insufficient scope
- 403 [`not_allowed_for_key`](https://developers.processcart.com/errors#not_allowed_for_key) — Not allowed for this key
- 404 [`not_found`](https://developers.processcart.com/errors#not_found) — Not found
- 405 [`method_not_allowed`](https://developers.processcart.com/errors#method_not_allowed) — Method not allowed
- 422 [`validation_failed`](https://developers.processcart.com/errors#validation_failed) — Validation failed
- 429 [`rate_limited`](https://developers.processcart.com/errors#rate_limited) — Too many requests
- 500 [`internal_error`](https://developers.processcart.com/errors#internal_error) — Internal error
- 503 [`unavailable`](https://developers.processcart.com/errors#unavailable) — Service unavailable

**Example response** (200)

```json
{
  "data": [
    {
      "id": "eb2383ee-da26-48db-aaa3-42e61dc67272",
      "webhookId": "2b64ebdd-e0ba-4d01-aca7-914b36d905aa",
      "eventId": "evt_9d68ebed-af3b-42da-aace-77503bb95cdc",
      "eventType": "webhook.test",
      "status": "delivered",
      "attemptCount": 1,
      "lastStatusCode": 200,
      "lastError": null,
      "lastAttemptAt": "2026-10-11T05:28:26.227Z",
      "nextAttemptAt": null,
      "deliveredAt": "2026-10-11T05:28:26.485Z",
      "createdAt": "2026-10-11T05:28:26.084Z"
    }
  ],
  "nextCursor": null,
  "hasMore": false
}
```


## GET /v1/webhooks/{id}/deliveries/{deliveryId}
**Get a delivery.** Scope `webhooks:manage`. Operation id `getWebhookDelivery` · [open in the API reference](https://developers.processcart.com/reference#tag/webhooks/GET/v1/webhooks/{id}/deliveries/{deliveryId}).

One delivery with the event envelope that was (or will be) POSTed — useful to inspect a failed delivery or to replay an event by hand.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string (uuid) | yes |  |
| `deliveryId` | string (uuid) | yes |  |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| 200 | OK. | [WebhookDeliveryWithPayload](https://developers.processcart.com/reference/schemas#webhookdeliverywithpayload) |
| 401 | No usable credential. `unauthorized` — Authentication required; `invalid_api_key` — Invalid API key; `key_revoked` — API key revoked. | [Problem](https://developers.processcart.com/errors) |
| 403 | `insufficient_scope` — Insufficient scope; `not_allowed_for_key` — Not allowed for this key. | [Problem](https://developers.processcart.com/errors) |
| 404 | `not_found` — Not found. | [Problem](https://developers.processcart.com/errors) |
| 405 | The verb is not supported on this path. `method_not_allowed` — Method not allowed. | [Problem](https://developers.processcart.com/errors) |
| 422 | `validation_failed` — Validation failed. | [Problem](https://developers.processcart.com/errors) |
| 429 | `rate_limited` — Too many requests. | [Problem](https://developers.processcart.com/errors) |
| 500 | `internal_error` — Internal error. | [Problem](https://developers.processcart.com/errors) |
| 503 | `unavailable` — Service unavailable. | [Problem](https://developers.processcart.com/errors) |

**Errors** (every code this operation can answer; see [Errors](https://developers.processcart.com/errors))

- 401 [`invalid_api_key`](https://developers.processcart.com/errors#invalid_api_key) — Invalid API key
- 401 [`key_revoked`](https://developers.processcart.com/errors#key_revoked) — API key revoked
- 401 [`unauthorized`](https://developers.processcart.com/errors#unauthorized) — Authentication required
- 403 [`insufficient_scope`](https://developers.processcart.com/errors#insufficient_scope) — Insufficient scope
- 403 [`not_allowed_for_key`](https://developers.processcart.com/errors#not_allowed_for_key) — Not allowed for this key
- 404 [`not_found`](https://developers.processcart.com/errors#not_found) — Not found
- 405 [`method_not_allowed`](https://developers.processcart.com/errors#method_not_allowed) — Method not allowed
- 422 [`validation_failed`](https://developers.processcart.com/errors#validation_failed) — Validation failed
- 429 [`rate_limited`](https://developers.processcart.com/errors#rate_limited) — Too many requests
- 500 [`internal_error`](https://developers.processcart.com/errors#internal_error) — Internal error
- 503 [`unavailable`](https://developers.processcart.com/errors#unavailable) — Service unavailable

**Example response** (200)

```json
{
  "id": "eb2383ee-da26-48db-aaa3-42e61dc67272",
  "webhookId": "2b64ebdd-e0ba-4d01-aca7-914b36d905aa",
  "eventId": "evt_9d68ebed-af3b-42da-aace-77503bb95cdc",
  "eventType": "webhook.test",
  "status": "delivered",
  "attemptCount": 1,
  "lastStatusCode": 200,
  "lastError": null,
  "lastAttemptAt": "2026-10-11T05:28:26.227Z",
  "nextAttemptAt": null,
  "deliveredAt": "2026-10-11T05:28:26.485Z",
  "createdAt": "2026-10-11T05:28:26.084Z",
  "payload": {
    "id": "evt_9d68ebed-af3b-42da-aace-77503bb95cdc",
    "org": {
      "id": "83b4ff3e-2634-423e-89ab-f2c5c07ced1f",
      "slug": "example-workspace"
    },
    "data": {
      "webhook": {
        "id": "2b64ebdd-e0ba-4d01-aca7-914b36d905aa"
      }
    },
    "type": "webhook.test",
    "actor": {
      "kind": "api",
      "name": "Zapier",
      "keyId": "d5ec9555-1a0c-455a-86e6-c7b18bcabc78"
    },
    "timestamp": "2026-10-11T05:28:26.084Z"
  }
}
```


## POST /v1/webhooks/{id}/deliveries/{deliveryId}/redeliver
**Send a delivery again.** Scope `webhooks:manage` · accepts `Idempotency-Key`. Operation id `redeliverWebhookDelivery` · [open in the API reference](https://developers.processcart.com/reference#tag/webhooks/POST/v1/webhooks/{id}/deliveries/{deliveryId}/redeliver).

Queues a finished delivery (delivered, failed or exhausted) again with the same `webhook-id` and sends it right away; the attempt count keeps counting. A delivery still in flight, or a disabled webhook, is refused. Audited.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string (uuid) | yes |  |
| `deliveryId` | string (uuid) | yes |  |

**Request headers**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Idempotency-Key` | string | no | Makes the request safe to retry: a second request with the same key and a byte-identical body (and the same `Expected-Revision`) replays the stored response (`Idempotent-Replayed: true`); a different body with the same key is refused (422 `idempotency_key_reused`) and no second resource is created. Keys are stored per workspace for 24 hours and replayed only to the API key that made the request (or the key one rotation away from it); another API key sending the same value is refused (422 `idempotency_key_reused`), so prefix keys per integration. 409, 429 and 5xx answers are never stored. |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| 202 | Accepted; the work completes asynchronously. | [WebhookQueuedDelivery](https://developers.processcart.com/reference/schemas#webhookqueueddelivery) |
| 401 | No usable credential. `unauthorized` — Authentication required; `invalid_api_key` — Invalid API key; `key_revoked` — API key revoked. | [Problem](https://developers.processcart.com/errors) |
| 403 | `insufficient_scope` — Insufficient scope; `not_allowed_for_key` — Not allowed for this key; `read_only_key` — Read-only key. | [Problem](https://developers.processcart.com/errors) |
| 404 | `not_found` — Not found. | [Problem](https://developers.processcart.com/errors) |
| 405 | The verb is not supported on this path. `method_not_allowed` — Method not allowed. | [Problem](https://developers.processcart.com/errors) |
| 409 | `delivery_not_terminal` — Delivery not finished; `idempotency_in_progress` — Request in progress; `webhook_disabled` — Webhook disabled. | [Problem](https://developers.processcart.com/errors) |
| 422 | `idempotency_key_reused` — Idempotency key reused; `validation_failed` — Validation failed. | [Problem](https://developers.processcart.com/errors) |
| 429 | `rate_limited` — Too many requests. | [Problem](https://developers.processcart.com/errors) |
| 500 | `internal_error` — Internal error. | [Problem](https://developers.processcart.com/errors) |
| 503 | `unavailable` — Service unavailable. | [Problem](https://developers.processcart.com/errors) |

**Errors** (every code this operation can answer; see [Errors](https://developers.processcart.com/errors))

- 401 [`invalid_api_key`](https://developers.processcart.com/errors#invalid_api_key) — Invalid API key
- 401 [`key_revoked`](https://developers.processcart.com/errors#key_revoked) — API key revoked
- 401 [`unauthorized`](https://developers.processcart.com/errors#unauthorized) — Authentication required
- 403 [`insufficient_scope`](https://developers.processcart.com/errors#insufficient_scope) — Insufficient scope
- 403 [`not_allowed_for_key`](https://developers.processcart.com/errors#not_allowed_for_key) — Not allowed for this key
- 403 [`read_only_key`](https://developers.processcart.com/errors#read_only_key) — Read-only key
- 404 [`not_found`](https://developers.processcart.com/errors#not_found) — Not found
- 405 [`method_not_allowed`](https://developers.processcart.com/errors#method_not_allowed) — Method not allowed
- 409 [`delivery_not_terminal`](https://developers.processcart.com/errors#delivery_not_terminal) — Delivery not finished
- 409 [`idempotency_in_progress`](https://developers.processcart.com/errors#idempotency_in_progress) — Request in progress
- 409 [`webhook_disabled`](https://developers.processcart.com/errors#webhook_disabled) — Webhook disabled
- 422 [`idempotency_key_reused`](https://developers.processcart.com/errors#idempotency_key_reused) — Idempotency key reused
- 422 [`validation_failed`](https://developers.processcart.com/errors#validation_failed) — Validation failed
- 429 [`rate_limited`](https://developers.processcart.com/errors#rate_limited) — Too many requests
- 500 [`internal_error`](https://developers.processcart.com/errors#internal_error) — Internal error
- 503 [`unavailable`](https://developers.processcart.com/errors#unavailable) — Service unavailable

**Example response** (202)

```json
{
  "delivery": {
    "id": "eb2383ee-da26-48db-aaa3-42e61dc67272",
    "webhookId": "2b64ebdd-e0ba-4d01-aca7-914b36d905aa",
    "attempt": 1
  }
}
```
