> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zapier.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Connection webhooks error handling

> Errors the Connections API returns to your requests, and the errors you return when receiving a webhook event.

# Connection webhooks error handling

There are two kinds of errors to handle:

1. **API errors:** what the Connections API returns when you call it to register or manage webhooks.
2. **Delivery errors:** what you return to Zapier when it POSTs an event to your `callback_url`, and how Zapier retries.

## API errors

Every error from the endpoints that register and manage webhooks (list, create, retrieve, update, delete) is returned as a JSON body with an `errors` array. Each error object has this shape:

| Field | Type | Required | Description |
| - | - | - | - |
| `code` | string | Yes | Machine-readable identifier for this occurrence. |
| `detail` | string | Yes | Human-readable explanation of this specific occurrence. |
| `status` | integer | No | HTTP status code, repeated in the body. |
| `title` | string | No | Short summary of the problem. |
| `source` | object | No | Reference to the source of the error, for example `{"pointer": "/callback_url"}` for a request-body field or `{"parameter": "event_type"}` for a query parameter. |

For example, a validation error identifies the offending field with `source`:

```json theme={null}
{
  "errors": [
    {
      "status": 400,
      "code": "invalid_field",
      "title": "Invalid Field",
      "detail": "callback_url must use HTTPS.",
      "source": { "pointer": "/callback_url" }
    }
  ]
}
```

Read `errors[0].code` to branch programmatically, and `errors[0].detail` for the explanation.

### HTTP status codes

| Status | `code` | Cause | Action |
| - | - | - | - |
| `400` | `invalid_field` (and similar) | A field is missing or invalid: a `callback_url` that is not HTTPS or points at an unsafe target, an unsupported `event_type`, or a `PATCH` with no fields. | Use `errors[0].source` and `errors[0].detail` to find the field, and correct the request. |
| `401` | `not_authenticated` | The request has no valid credentials. | Send a valid token as `Authorization: Bearer YOUR_TOKEN`. To obtain one, go to [Token exchange: Connection Webhooks API](/white-label/implementation/token-exchange#c-connection-webhooks-api-embedded). |
| `403` | `permission_denied` | The token is authenticated but not allowed: the account is not a White Label partner account, or the token is missing the required scope. | Use a White Label partner token with the `connection:webhook:read` or `connection:webhook:write` scope. |
| `404` | `not_found` | The webhook ID does not exist, or belongs to a webhook your account does not manage. | Confirm the ID and that it belongs to your account. |
| `409` | `webhook_already_exists` | An active webhook for the same `event_type` already exists. You can have only one active webhook per event type. | Reuse or update the existing webhook, or set it to `is_active: false` first. List your webhooks to find it. |
| `429` | (rate limited) | You exceeded the rate limit. | Check the `Retry-After` response header and wait that many seconds. Apply exponential backoff. |

## Delivery errors

When Zapier POSTs an event to your `callback_url`, the status you return controls whether Zapier retries.

* **Success (`2xx`):** the delivery is acknowledged and not retried.
* **Retryable failure (`429` or `5xx`):** the delivery is retried later. A timeout or connection error is also retried.
* **Permanent failure (any other `4xx`):** the delivery is not retried. Return one only when the delivery is genuinely unprocessable, such as a signature that does not verify.

Verify the signature before you act on any delivery. For the steps, go to [Verify signatures](/white-label/connection-webhooks/verify-signatures).

### Retries and Retry-After

Retryable failures are retried a few times with increasing backoff, over roughly 25 minutes. If every attempt fails, the event is dropped and not delivered again.

If your endpoint returns a `429` or `5xx` with a `Retry-After` header, Zapier honors it as the delay before the next attempt, in place of the default backoff. Only the integer-seconds form is honored (for example, `Retry-After: 120`); the HTTP-date form is ignored, and Zapier falls back to its default backoff. The delay is capped at 600 seconds (10 minutes).

Because a delivery can be retried, the same event can arrive more than once. Deduplicate on the `webhook-id` header and make your handler idempotent.

## Related

* [Verify signatures](/white-label/connection-webhooks/verify-signatures)
* [Event payload reference](/white-label/connection-webhooks/payload-reference)
* [Connections API reference](/api-reference/connections/connection-webhooks/create-a-connection-webhook)
