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

# List Webhooks

> List every webhook subscription on the account — newest first, secrets never included.

Lists every webhook subscription on your account, newest first. Use it to audit what is subscribed before [creating](/docs/developers/api-reference/webhooks/create) another (accounts cap at **10**) and to spot subscriptions that have been auto-disabled.

Signing secrets are **never** included — they are shown only once, in the [create](/docs/developers/api-reference/webhooks/create) response. A lost secret cannot be recovered: [delete](/docs/developers/api-reference/webhooks/delete) the subscription and create a new one.

**Requirements:** `webhooks:manage` scope + the `public_api_webhooks` feature.

## Request

No parameters. The list is not paginated — an account holds at most 10 subscriptions.

## Response

<ResponseField name="webhooks" type="object[]">
  <Expandable title="webhook">
    <ResponseField name="id" type="string">
      Webhook subscription ID.
    </ResponseField>

    <ResponseField name="url" type="string">
      The destination URL receiving deliveries.
    </ResponseField>

    <ResponseField name="eventTypes" type="string[]">
      Subscribed event types from the [event catalog](/docs/developers/api-reference/updates/poll).
    </ResponseField>

    <ResponseField name="status" type="string">
      `ACTIVE` or `DISABLED`. Disabled subscriptions receive no deliveries.
    </ResponseField>

    <ResponseField name="createdAt" type="string">
      ISO creation timestamp.
    </ResponseField>

    <ResponseField name="disabledAt" type="string | null">
      When the subscription was disabled; `null` while `ACTIVE`.
    </ResponseField>

    <ResponseField name="disabledReason" type="string | null">
      Why it was disabled (e.g. repeated delivery failures). Recover by [deleting](/docs/developers/api-reference/webhooks/delete) and re-creating the subscription.
    </ResponseField>
  </Expandable>
</ResponseField>

## Errors

| Status | `code`         | Meaning                                                            |
| ------ | -------------- | ------------------------------------------------------------------ |
| `401`  | `UNAUTHORIZED` | Missing or invalid token                                           |
| `403`  | `FORBIDDEN`    | Missing `webhooks:manage` scope, or `public_api_webhooks` disabled |

<RequestExample>
  ```bash curl theme={null}
  curl -sS https://app.opentrain.ai/api/public/v1/webhooks \
    -H "Authorization: Bearer $OT_API_TOKEN"
  ```

  ```bash CLI theme={null}
  opentrain webhooks list --json
  ```

  ```json MCP: opentrain_list_webhooks theme={null}
  {}
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "webhooks": [
      {
        "id": "<WEBHOOK_ID>",
        "url": "https://example.com/hooks/opentrain",
        "eventTypes": ["proposal.received", "message.received", "approval.confirmed"],
        "status": "ACTIVE",
        "createdAt": "2026-06-12T10:00:00.000Z",
        "disabledAt": null,
        "disabledReason": null
      },
      {
        "id": "<WEBHOOK_ID_2>",
        "url": "https://example.com/hooks/old-endpoint",
        "eventTypes": ["payment.pending"],
        "status": "DISABLED",
        "createdAt": "2026-05-30T08:00:00.000Z",
        "disabledAt": "2026-06-10T14:20:00.000Z",
        "disabledReason": "Disabled after repeated delivery failures"
      }
    ]
  }
  ```
</ResponseExample>
