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

# Manage webhooks

> Create, edit, and delete webhook subscriptions from the Openlayer dashboard or the REST API.

Webhook subscriptions are managed at the **workspace level**. Each subscription
defines an HTTPS endpoint and the [event types](/security/webhooks/events) it
should receive. You can manage subscriptions in two ways:

* From the **Openlayer dashboard**, under your workspace settings.
* Programmatically, through the [REST API](/api-reference/rest/overview).

<Info>
  Only **workspace admins** can create and manage webhooks, see [Roles and
  permissions](/security/roles-and-permissions) for more details.
</Info>

## Manage webhooks in the dashboard

The webhooks settings page is where most users create and monitor their
subscriptions.

<Steps>
  <Step title="Open your workspace settings">
    Click the workspace name in the upper-left corner, select **Workspace
    Settings**, then open the **Webhooks** section.
  </Step>

  <Step title="Add a webhook">
    On the **Webhooks** tab, create a new subscription and fill in the form:

    * **URL** — the HTTPS endpoint that will receive events.
    * **Event types** — one or more [event types](/security/webhooks/events) to
      subscribe to.
    * **Description** — an optional label to help you identify the subscription.

    New subscriptions are enabled by default.
  </Step>

  <Step title="Copy the signing secret">
    After you create the subscription, Openlayer shows the **signing secret**
    once. Copy it and store it securely — you'll use it to [verify
    signatures](/security/webhooks/verify-signatures), and it can't be retrieved
    later.
  </Step>

  <Step title="Edit or delete subscriptions">
    Each subscription in the list can be edited (to change its URL, event types,
    description, or enabled status) or deleted. Disabling a subscription pauses
    deliveries without removing it.
  </Step>
</Steps>

### View deliveries

Switch to the **Deliveries** tab to see recent delivery attempts. Each attempt
shows whether it succeeded, failed, or is still pending, along with the HTTP
status code and response time. Select a delivery to inspect its details,
including the response body or error message — useful for debugging an endpoint
that isn't receiving events as expected.

<Note>
  Delivery records are retained for 90 days. For how deliveries and retries
  work, see the [Webhooks overview](/security/webhooks/overview#retries).
</Note>

## Manage webhooks with the REST API

If you'd rather manage subscriptions programmatically — for example, to provision
them as part of your infrastructure — use the REST API.

### Before you begin

All requests are authenticated with an API key passed as a bearer token, and are
made against the base URL `https://api.openlayer.com/v1`:

```text theme={null}
Authorization: Bearer YOUR_API_KEY_HERE
```

See [Create an API key](/workspace-and-projects/find-your-api-key) if you don't
have one yet. The examples below use `{workspaceId}`, the UUID of your workspace,
which you can find in your workspace settings.

### Create a webhook subscription

Send a `POST` request with the endpoint `url` and the `eventTypes` you want to
subscribe to.

```bash theme={null}
curl -X POST "https://api.openlayer.com/v1/workspaces/{workspaceId}/webhooks" \
  -H "Authorization: Bearer YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/openlayer",
    "description": "Production alerting",
    "eventTypes": ["test.created", "tests.result.updated"]
  }'
```

The request body accepts the following fields:

| Field         | Type      | Required | Description                                                           |
| ------------- | --------- | -------- | --------------------------------------------------------------------- |
| `url`         | string    | Yes      | The HTTPS endpoint to deliver events to (max 2048 characters).        |
| `eventTypes`  | string\[] | Yes      | One or more [event types](/security/webhooks/events) to subscribe to. |
| `description` | string    | No       | An optional human-readable description (max 500 characters).          |
| `enabled`     | boolean   | No       | Whether the subscription is active. Defaults to `true`.               |

The response returns the new subscription's `id` and its **signing secret**:

```json theme={null}
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "secret": "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
}
```

<Warning>
  The signing secret is returned **only once**, at creation time. Store it
  securely — it cannot be retrieved later. You'll use it to [verify webhook
  signatures](/security/webhooks/verify-signatures). If you lose it, delete the
  subscription and create a new one.
</Warning>

### List webhook subscriptions

```bash theme={null}
curl "https://api.openlayer.com/v1/workspaces/{workspaceId}/webhooks" \
  -H "Authorization: Bearer YOUR_API_KEY_HERE"
```

```json theme={null}
{
  "items": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "workspaceId": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
      "url": "https://example.com/webhooks/openlayer",
      "description": "Production alerting",
      "eventTypes": ["test.created", "tests.result.updated"],
      "enabled": true,
      "creatorId": "589ece63-49a2-41b4-98e1-10547761d4b0",
      "dateCreated": "2026-01-15T10:00:00Z",
      "dateUpdated": "2026-01-15T10:00:00Z"
    }
  ]
}
```

The endpoint is paginated with the `page` and `perPage` query parameters. Note
that the signing secret is never included when listing or retrieving
subscriptions.

### Retrieve a webhook subscription

```bash theme={null}
curl "https://api.openlayer.com/v1/workspaces/{workspaceId}/webhooks/{webhookId}" \
  -H "Authorization: Bearer YOUR_API_KEY_HERE"
```

Returns the same subscription object shown above, or `404 Not Found` if the
subscription does not exist.

### Update a webhook subscription

Send a `PUT` request with the fields you want to change. You can update the
`url`, `description`, `eventTypes`, and `enabled` status.

```bash theme={null}
curl -X PUT "https://api.openlayer.com/v1/workspaces/{workspaceId}/webhooks/{webhookId}" \
  -H "Authorization: Bearer YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "eventTypes": ["test.created", "test.updated", "test.deleted"],
    "enabled": false
  }'
```

Setting `enabled` to `false` lets you pause deliveries without deleting the
subscription. The response returns the updated subscription object.

### Delete a webhook subscription

```bash theme={null}
curl -X DELETE "https://api.openlayer.com/v1/workspaces/{workspaceId}/webhooks/{webhookId}" \
  -H "Authorization: Bearer YOUR_API_KEY_HERE"
```

A successful delete returns `204 No Content`.

### List delivery attempts

To debug deliveries, list the recent attempts for a subscription. Each record
describes one attempt, including the HTTP status code and response time.

```bash theme={null}
curl "https://api.openlayer.com/v1/workspaces/{workspaceId}/webhooks/{webhookId}/deliveries" \
  -H "Authorization: Bearer YOUR_API_KEY_HERE"
```

```json theme={null}
{
  "items": [
    {
      "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
      "eventId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "attemptNumber": 1,
      "success": true,
      "statusCode": 200,
      "responseBody": "{\"status\":\"ok\"}",
      "responseTimeMs": 150,
      "errorMessage": null,
      "dateCreated": "2026-01-21T10:30:05Z"
    }
  ]
}
```

| Field            | Description                                                        |
| ---------------- | ------------------------------------------------------------------ |
| `attemptNumber`  | Which attempt this record represents (`1` is the initial attempt). |
| `success`        | Whether the attempt received a `2xx` response.                     |
| `statusCode`     | The HTTP status code returned, or `null` if the connection failed. |
| `responseBody`   | The first 1 KB of the response body, for debugging.                |
| `responseTimeMs` | How long the attempt took, in milliseconds.                        |
| `errorMessage`   | The error, if the attempt failed.                                  |

This endpoint is paginated with the `page` and `perPage` query parameters.
Delivery records are retained for 90 days. For more on how deliveries and retries
work, see the [Webhooks overview](/security/webhooks/overview#retries).
