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

# Webhook

A Webhook is an endpoint on your server that Whop sends signed HTTP POST requests to when events happen, such as a payment succeeding or a membership going active. A webhook is attached to an account or an app and subscribes to the events you choose.

Use the Webhooks API to create and update endpoints, send a test event, inspect the delivery log, and replay deliveries your server missed. See [Webhooks & Events](/developer/guides/webhooks) for verifying signatures and handling retries.

## Endpoints

| Endpoint | Request |
| - | - |
| [List Webhooks](/api-reference/beta/webhooks/list-webhooks) | <Badge color="blue" size="sm" stroke>GET</Badge> `/webhooks` |
| [Retrieve Webhook](/api-reference/beta/webhooks/retrieve-webhook) | <Badge color="blue" size="sm" stroke>GET</Badge> `/webhooks/{id}` |
| [List Deliveries](/api-reference/beta/webhooks/list-deliveries) | <Badge color="blue" size="sm" stroke>GET</Badge> `/webhooks/{id}/deliveries` |
| [Create Webhook](/api-reference/beta/webhooks/create-webhook) | <Badge color="green" size="sm" stroke>POST</Badge> `/webhooks` |
| [Replay Delivery](/api-reference/beta/webhooks/replay-delivery) | <Badge color="green" size="sm" stroke>POST</Badge> `/webhooks/{id}/deliveries/{delivery_id}/replay` |
| [Replay Deliveries in a Range](/api-reference/beta/webhooks/replay-deliveries-in-a-range) | <Badge color="green" size="sm" stroke>POST</Badge> `/webhooks/{id}/replay` |
| [Send Test Event](/api-reference/beta/webhooks/send-test-event) | <Badge color="green" size="sm" stroke>POST</Badge> `/webhooks/{id}/test` |
| [Update Webhook](/api-reference/beta/webhooks/update-webhook) | <Badge color="orange" size="sm" stroke>PATCH</Badge> `/webhooks/{id}` |
| [Delete Webhook](/api-reference/beta/webhooks/delete-webhook) | <Badge color="red" size="sm" stroke>DELETE</Badge> `/webhooks/{id}` |

## Attributes

<Columns cols={2}>
  <Column>
    <ResponseField name="id" type="string" required>
      Webhook ID, prefixed `hook_`.
    </ResponseField>

    <ResponseField name="api_version" type="string" required>
      The API version used to format payloads sent to this webhook endpoint.

      Available options: `v1`, `v2`, `v5`
    </ResponseField>

    <ResponseField name="api_version_date" type="string | null" required>
      The dated API version (Api-Version-Date) that v1 payloads for this endpoint
      are pinned to: events serialize exactly like a REST read at this version (the
      native serializer where the resource has one). Null when unpinned — legacy
      (v2/v5) webhooks, and v1 webhooks on the legacy payload shape.
    </ResponseField>

    <ResponseField name="child_resource_events" type="boolean" required>
      Whether events are sent for child resources. For example, if the webhook is on
      an account, enabling this sends events only from its connected accounts.
    </ResponseField>

    <ResponseField name="consecutive_failures" type="integer" required>
      Number of consecutive deliveries whose first attempt to this endpoint failed
      since it last accepted one. Later retries of the same delivery do not
      increment it. Resets to `0` when a delivery succeeds or the webhook is
      re-enabled.
    </ResponseField>

    <ResponseField name="created_at" type="string" required>
      When the webhook was created, as an ISO 8601 timestamp.
    </ResponseField>

    <ResponseField name="disabled_at" type="string | null" required>
      When Whop automatically disabled this webhook, as an ISO 8601 timestamp.
      `null` unless the webhook was disabled by Whop; a webhook you disabled
      yourself has `enabled: false` and a `null` `disabled_at`.
    </ResponseField>

    <ResponseField name="disabled_reason" type="string | null" required>
      Why Whop disabled this webhook. `delivery_failures` means every delivery failed for 3 days straight. `null` when `disabled_at` is `null`.

      Available options: `delivery_failures`
    </ResponseField>

    <ResponseField name="enabled" type="boolean" required>
      Whether this webhook endpoint is currently active and receiving events.
    </ResponseField>

    <ResponseField name="events" type="string[]" required>
      Event types this webhook is subscribed to, in dot form (for example `payment.succeeded`).

      Available options: `account.updated`, `account.financing_approved`, `account.financing_denied`, `invoice.created`, `invoice.marked_uncollectible`, `invoice.paid`, `invoice.past_due`, `invoice.voided`, `membership.activated`, `membership.deactivated`, `membership.trial_ending_soon`, `membership.updated`, `entry.created`, `entry.approved`, `entry.denied`, `entry.deleted`, `export.completed`, `export.failed`, `setup_intent.requires_action`, `setup_intent.succeeded`, `setup_intent.canceled`, `ledger_account.funds_available`, `swap.completed`, `deposit.succeeded`, `financial_activity.funds_available`, `transfer.created`, `transfer.completed`, `transfer.failed`, `withdrawal.created`, `withdrawal.updated`, `withdrawal.reversed`, `payout.created`, `payout.updated`, `payout.reversed`, `card_transaction.created`, `card_transaction.updated`, `card_transaction.completed`, `card_transaction.declined`, `card_transaction.reversed`, `card.created`, `card.updated`, `card.frozen`, `card.canceled`, `card_application.created`, `card_application.updated`, `card_application.approved`, `card_application.denied`, `course_lesson_interaction.completed`, `payout_method.created`, `verification.succeeded`, `identity_profile.approved`, `identity_profile.rejected`, `identity_profile.needs_action`, `identity_profile.updated`, `payout_account.status_updated`, `payment.authorized`, `payment.canceled`, `resolution_center_case.created`, `resolution_center_case.updated`, `resolution_center_case.decided`, `product.created`, `product.updated`, `product.deleted`, `product.published`, `product.unpublished`, `plan.created`, `plan.updated`, `plan.deleted`, `shipment.created`, `shipment.updated`, `member.created`, `member.updated`, `ad_campaign.payment_failed`, `ad_campaign.updated`, `ad_campaign.events`, `ad.updated`, `chat.message.created`, `chat.reaction.created`, `payment.created`, `payment.succeeded`, `payment.failed`, `payment.pending`, `payment.requires_action`, `dispute.created`, `dispute.updated`, `refund.created`, `refund.updated`, `dispute_alert.created`, `membership.cancel_at_period_end_changed`, `membership.went_valid`, `membership.went_invalid`, `membership.metadata_updated`, `resolution.created`, `resolution.updated`, `resolution.decided`, `payment.affiliate_reward_created`, `membership.experience_claimed`, `app_membership.went_valid`, `app_membership.went_invalid`, `app_payment.created`, `app_payment.succeeded`, `app_payment.failed`, `app_payment.pending`, `app_payment.requires_action`, `app_membership.cancel_at_period_end_changed`
    </ResponseField>

    <ResponseField name="failing_since" type="string | null" required>
      When the current failure streak began, as an ISO 8601 timestamp. Unlike
      `last_failure_at`, this is set on the streak's first failed attempt, so it
      shows an endpoint that is failing right now. `null` when the endpoint is
      healthy.
    </ResponseField>

    <ResponseField name="last_failure_at" type="string | null" required>
      When a delivery to this endpoint most recently failed after exhausting
      retries, as an ISO 8601 timestamp. `null` if no delivery has ever failed.
    </ResponseField>

    <ResponseField name="resource_id" type="string" required>
      ID of the resource (account or app) this webhook is attached to.
    </ResponseField>

    <ResponseField name="testable_events" type="string[]" required>
      The subset of subscribed event types that support sending test payloads, in dot form.

      Available options: `account.updated`, `account.financing_approved`, `account.financing_denied`, `invoice.created`, `invoice.marked_uncollectible`, `invoice.paid`, `invoice.past_due`, `invoice.voided`, `membership.activated`, `membership.deactivated`, `membership.trial_ending_soon`, `membership.updated`, `entry.created`, `entry.approved`, `entry.denied`, `entry.deleted`, `export.completed`, `export.failed`, `setup_intent.requires_action`, `setup_intent.succeeded`, `setup_intent.canceled`, `ledger_account.funds_available`, `swap.completed`, `deposit.succeeded`, `financial_activity.funds_available`, `transfer.created`, `transfer.completed`, `transfer.failed`, `withdrawal.created`, `withdrawal.updated`, `withdrawal.reversed`, `payout.created`, `payout.updated`, `payout.reversed`, `card_transaction.created`, `card_transaction.updated`, `card_transaction.completed`, `card_transaction.declined`, `card_transaction.reversed`, `card.created`, `card.updated`, `card.frozen`, `card.canceled`, `card_application.created`, `card_application.updated`, `card_application.approved`, `card_application.denied`, `course_lesson_interaction.completed`, `payout_method.created`, `verification.succeeded`, `identity_profile.approved`, `identity_profile.rejected`, `identity_profile.needs_action`, `identity_profile.updated`, `payout_account.status_updated`, `payment.authorized`, `payment.canceled`, `resolution_center_case.created`, `resolution_center_case.updated`, `resolution_center_case.decided`, `product.created`, `product.updated`, `product.deleted`, `product.published`, `product.unpublished`, `plan.created`, `plan.updated`, `plan.deleted`, `shipment.created`, `shipment.updated`, `member.created`, `member.updated`, `ad_campaign.payment_failed`, `ad_campaign.updated`, `ad_campaign.events`, `ad.updated`, `chat.message.created`, `chat.reaction.created`, `payment.created`, `payment.succeeded`, `payment.failed`, `payment.pending`, `payment.requires_action`, `dispute.created`, `dispute.updated`, `refund.created`, `refund.updated`, `dispute_alert.created`, `membership.cancel_at_period_end_changed`, `membership.went_valid`, `membership.went_invalid`, `membership.metadata_updated`, `resolution.created`, `resolution.updated`, `resolution.decided`, `payment.affiliate_reward_created`, `membership.experience_claimed`, `app_membership.went_valid`, `app_membership.went_invalid`, `app_payment.created`, `app_payment.succeeded`, `app_payment.failed`, `app_payment.pending`, `app_payment.requires_action`, `app_membership.cancel_at_period_end_changed`
    </ResponseField>

    <ResponseField name="url" type="string" required>
      Destination URL where webhook payloads are delivered via HTTP POST.
    </ResponseField>

    <ResponseField name="webhook_secret" type="string | null" required>
      Secret key used to sign webhook payloads for verification. Include this in
      your HMAC validation logic. Returned on the create response and to interactive
      dashboard sessions; `null` for API-key and OAuth callers on later reads.
    </ResponseField>
  </Column>

  <Column>
    <div className="api-resource-sticky-example">
      ```json Webhook theme={null}
      {
      	"id": "hook_xxxxxxxxxxxxxx",
      	"resource_id": "biz_xxxxxxxxxxxxxx",
      	"url": "https://example.com/webhooks/whop",
      	"enabled": true,
      	"api_version": "v1",
      	"api_version_date": "2026-09-01",
      	"events": ["payment.succeeded", "membership.activated"],
      	"child_resource_events": false,
      	"testable_events": ["payment.succeeded", "membership.activated"],
      	"consecutive_failures": 0,
      	"failing_since": null,
      	"last_failure_at": "2026-08-28T03:12:45.000Z",
      	"disabled_at": null,
      	"disabled_reason": null,
      	"created_at": "2026-08-02T18:20:00.000Z",
      	"webhook_secret": null
      }
      ```
    </div>
  </Column>
</Columns>


## Related topics

- [Webhooks](/developer/guides/webhooks.md)
- [Webhook](/api-reference/webhooks/webhook.md)
- [Create webhook](/api-reference/webhooks/create-webhook.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.