ThriveCart delivers account events to subscriber endpoints over HTTP POST. Two surfaces exist and they do not share event names. **Event Subscription API (this document).** Created programmatically with `POST https://thrivecart.com/api/external/subscribe`, taking at least `event` (an event key, or `*` for all) and `target_url`. Optional `trigger_fields` narrow delivery to specific products, bumps, upsells, downsells, affiliates or modes. Deliveries are **always JSON** in the request body. Removal is `POST /unsubscribe` with the endpoint `url`. **Account-wide webhooks (see x-legacy-webhooks).** Configured in the UI under Settings > API & Webhooks > Webhooks & Notifications, up to 5 destinations by default, delivered as `x-www-form-urlencoded` with a different, dotted event vocabulary. **Delivery identity.** Every event-subscription delivery carries `webhook_id`, a UUID that identifies that specific HTTP POST. It is stable across retries of the same delivery and is the documented idempotency key. `event_id` is retained for backward compatibility but is tied to the transaction/event record and may be absent on some event types. **Authenticity.** Payloads carry `thrivecart_secret` (the account's secret word) and `thrivecart_account`. There is no HMAC signature header and no timestamp, so replay protection is the consumer's responsibility. **Target URL restriction.** For OAuth applications, `target_url` must begin with a URL registered in the app's settings, the same way redirect URLs are registered. This does not apply to account-wide API keys.
View SpecView on GitHubCompanyCheckoutShopping CartPaymentsE-CommerceSubscriptionAffiliate MarketingLearning ManagementCreator EconomyWebhookAsyncAPIEventsWebhooks
Channels
order_created
order_payment_product
order_payment_bump
order_payment_upsell
order_payment_downsell
order_rebill
order_rebill_failed
order_rebill_completed
order_rebill_cancelled
order_refund_product
order_refund_bump
order_refund_upsell
order_refund_downsell
subscription_paused
subscription_resumed
cart_abandoned
affiliate_approved
affiliate_rejected
affiliate_commission_earned
affiliate_commission_payout
affiliate_commission_refund
Servers
https
subscriber
The consumer's own HTTPS endpoint, registered as target_url on POST /api/external/subscribe. ThriveCart is the publisher; there is no ThriveCart-hosted broker.
# Derived by API Evangelist from ThriveCart's own Event Subscription API documentation.
# Source: https://developers.thrivecart.com/documentation/event_subscription/intro/ and the
# 21 per-event pages linked from it, read 2026-08-12.
# ThriveCart publishes no AsyncAPI of its own. Every channel, event key and trigger field below
# is carried over from those pages; nothing is invented. Payload schemas are NOT documented by
# ThriveCart, so message payloads are left open (type: object) rather than guessed.
asyncapi: 3.0.0
info:
title: ThriveCart Event Subscriptions
version: '1'
description: >
ThriveCart delivers account events to subscriber endpoints over HTTP POST. Two surfaces
exist and they do not share event names.
**Event Subscription API (this document).** Created programmatically with
`POST https://thrivecart.com/api/external/subscribe`, taking at least `event` (an event key,
or `*` for all) and `target_url`. Optional `trigger_fields` narrow delivery to specific
products, bumps, upsells, downsells, affiliates or modes. Deliveries are **always JSON** in
the request body. Removal is `POST /unsubscribe` with the endpoint `url`.
**Account-wide webhooks (see x-legacy-webhooks).** Configured in the UI under
Settings > API & Webhooks > Webhooks & Notifications, up to 5 destinations by default,
delivered as `x-www-form-urlencoded` with a different, dotted event vocabulary.
**Delivery identity.** Every event-subscription delivery carries `webhook_id`, a UUID that
identifies that specific HTTP POST. It is stable across retries of the same delivery and is
the documented idempotency key. `event_id` is retained for backward compatibility but is tied
to the transaction/event record and may be absent on some event types.
**Authenticity.** Payloads carry `thrivecart_secret` (the account's secret word) and
`thrivecart_account`. There is no HMAC signature header and no timestamp, so replay
protection is the consumer's responsibility.
**Target URL restriction.** For OAuth applications, `target_url` must begin with a URL
registered in the app's settings, the same way redirect URLs are registered. This does not
apply to account-wide API keys.
contact:
name: ThriveCart Developer Support
url: https://developers.thrivecart.com/documentation/event_subscription/intro/
email: support@thrivecart.com
externalDocs:
description: Event Subscription API
url: https://developers.thrivecart.com/documentation/event_subscription/intro/
defaultContentType: application/json
servers:
subscriber:
host: '{target_url_host}'
protocol: https
description: >-
The consumer's own HTTPS endpoint, registered as target_url on POST /api/external/subscribe.
ThriveCart is the publisher; there is no ThriveCart-hosted broker.
variables:
target_url_host:
description: Host of the subscriber endpoint. For OAuth apps it must match a URL
registered in the application settings.
default: example.com
components:
messageTraits:
thrivecartEvent:
headers:
type: object
properties:
Content-Type:
type: string
const: application/json
payload:
type: object
description: >-
ThriveCart does not publish payload schemas for event subscriptions. The fields below
are the delivery-envelope fields it documents explicitly; the remainder of the body
varies by event and is only observable at runtime.
properties:
webhook_id:
type: string
format: uuid
description: UUID identifying this delivery. Stable across retries. Use as the
idempotency key.
event_id:
type: string
description: Legacy identifier tied to the transaction/event record. May be absent on
some event types.
event:
type: string
description: The event key that matched.
mode_int:
type: integer
enum: [1, 2]
description: 1 = test mode, 2 = live mode.
thrivecart_account:
type: string
description: Account identifier.
thrivecart_secret:
type: string
description: The account's secret word, for authenticity verification by the receiver.
additionalProperties: true
channels:
order_created:
address: order_created
messages:
orderCreated:
name: order_created
title: Order created
summary: An order is made. Triggers once per order; order_payment_product and siblings are
usually the better choice.
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: mode_int
required: false
type: numeric
description: 1 for test-mode purchases only, 2 for live-mode purchases only.
order_payment_product:
address: order_payment_product
messages:
orderPaymentProduct:
name: order_payment_product
title: Product purchased
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: mode_int
required: false
type: numeric
- name: base_product
required: false
type: numeric or array
description: 'Numeric product ID, or array of product IDs. Example: 5 or [5, 19, 30].'
order_payment_bump:
address: order_payment_bump
messages:
orderPaymentBump:
name: order_payment_bump
title: Bump purchased
summary: A bump's ID is the same as the product it is attached to.
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: mode_int
required: false
type: numeric
- name: purchase.bump_id
required: false
type: numeric or array
x-example-subscription: '{"event": "order_payment_bump", "target_url":
"https://mysite.com/webhooks/123/", "trigger_fields": {"mode_int": 2, "purchase":
{"bump_id": 5}}}'
order_payment_upsell:
address: order_payment_upsell
messages:
orderPaymentUpsell:
name: order_payment_upsell
title: Upsell purchased
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: mode_int
required: false
type: numeric
- name: purchase.upsell_id
required: false
type: numeric or array
order_payment_downsell:
address: order_payment_downsell
messages:
orderPaymentDownsell:
name: order_payment_downsell
title: Downsell purchased
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: mode_int
required: false
type: numeric
- name: purchase.downsell_id
required: false
type: numeric or array
order_rebill:
address: order_rebill
messages:
orderRebill:
name: order_rebill
title: Recurring payment made
summary: Fires for a subscription or a split pay. Bumps do not support subscriptions.
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: mode_int
required: false
type: numeric
- name: subscription.type
required: false
type: enum
enum: [product, upsell, downsell]
- name: subscription.product_id
required: false
type: numeric
- name: subscription.upsell_id
required: false
type: numeric
- name: subscription.downsell_id
required: false
type: numeric
order_rebill_failed:
address: order_rebill_failed
messages:
orderRebillFailed:
name: order_rebill_failed
title: Recurring payment failed
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: mode_int
required: false
type: numeric
- name: subscription.type
required: false
type: enum
enum: [product, upsell, downsell]
- name: subscription.product_id
required: false
type: numeric
- name: subscription.upsell_id
required: false
type: numeric
- name: subscription.downsell_id
required: false
type: numeric
order_rebill_completed:
address: order_rebill_completed
messages:
orderRebillCompleted:
name: order_rebill_completed
title: Subscription completed all payments
summary: Split pay finished, or a subscription with a limited number of rebills. Fires at
the same time as the final order_rebill.
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: mode_int
required: false
type: numeric
- name: subscription.type
required: false
type: enum
enum: [product, upsell, downsell]
order_rebill_cancelled:
address: order_rebill_cancelled
messages:
orderRebillCancelled:
name: order_rebill_cancelled
title: Subscription cancelled
summary: No further payments are due.
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: mode_int
required: false
type: numeric
- name: subscription.type
required: false
type: enum
enum: [product, upsell, downsell]
order_refund_product:
address: order_refund_product
messages:
orderRefundProduct:
name: order_refund_product
title: Product refunded
summary: Full or partial.
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: mode_int
required: false
type: numeric
- name: base_product
required: false
type: numeric or array
order_refund_bump:
address: order_refund_bump
messages:
orderRefundBump:
name: order_refund_bump
title: Bump refunded
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: mode_int
required: false
type: numeric
- name: purchase.bump_id
required: false
type: numeric or array
order_refund_upsell:
address: order_refund_upsell
messages:
orderRefundUpsell:
name: order_refund_upsell
title: Upsell refunded
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: mode_int
required: false
type: numeric
- name: purchase.upsell_id
required: false
type: numeric or array
order_refund_downsell:
address: order_refund_downsell
messages:
orderRefundDownsell:
name: order_refund_downsell
title: Downsell refunded
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: mode_int
required: false
type: numeric
- name: purchase.downsell_id
required: false
type: numeric or array
subscription_paused:
address: subscription_paused
messages:
subscriptionPaused:
name: subscription_paused
title: Subscription paused
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: mode_int
required: false
type: numeric
- name: subscription.type
required: false
type: enum
enum: [product, upsell, downsell]
subscription_resumed:
address: subscription_resumed
messages:
subscriptionResumed:
name: subscription_resumed
title: Subscription resumed
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: mode_int
required: false
type: numeric
- name: subscription.type
required: false
type: enum
enum: [product, upsell, downsell]
cart_abandoned:
address: cart_abandoned
messages:
cartAbandoned:
name: cart_abandoned
title: Cart abandoned
summary: A customer entered their email address on the cart page but left without
purchasing.
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: base_product
required: false
type: numeric or array
affiliate_approved:
address: affiliate_approved
messages:
affiliateApproved:
name: affiliate_approved
title: Affiliate approved for a product
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: product_id
required: false
type: numeric or array
affiliate_rejected:
address: affiliate_rejected
messages:
affiliateRejected:
name: affiliate_rejected
title: Affiliate rejected or access revoked
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: product_id
required: false
type: numeric or array
affiliate_commission_earned:
address: affiliate_commission_earned
messages:
affiliateCommissionEarned:
name: affiliate_commission_earned
title: Affiliate earned commission
summary: Affiliate payouts only happen in live mode, so this never fires in test mode.
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: affiliate_user_id
required: false
type: numeric or array
affiliate_commission_payout:
address: affiliate_commission_payout
messages:
affiliateCommissionPayout:
name: affiliate_commission_payout
title: Affiliate commission paid
summary: Also fires for manual payouts. Live mode only.
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: affiliate_user_id
required: false
type: numeric or array
affiliate_commission_refund:
address: affiliate_commission_refund
messages:
affiliateCommissionRefund:
name: affiliate_commission_refund
title: Affiliate commission refunded
summary: Live mode only.
traits: [$ref: '#/components/messageTraits/thrivecartEvent']
x-trigger-fields:
- name: affiliate_user_id
required: false
type: numeric or array
operations:
receiveThriveCartEvent:
action: receive
channel:
$ref: '#/channels/order_created'
title: Receive a ThriveCart event subscription delivery
summary: >-
Subscribe with POST https://thrivecart.com/api/external/subscribe, body
{"event": "<key>", "target_url": "<https url>", "trigger_fields": {...}}. Use "*" as the
event key to receive every event, which is equivalent to creating a webhook in the account.
Unsubscribe with POST /api/external/unsubscribe and the endpoint url.
x-legacy-webhooks:
description: >-
The UI-configured, account-wide webhook surface. Separate vocabulary, separate encoding.
Documented at https://support.thrivecart.com/help/using-webhook-notifications/.
configured_at: Settings > API & Webhooks > Webhooks & Notifications
max_destinations: 5
method: POST
content_type: application/x-www-form-urlencoded
activation_requirement: the endpoint must answer HTTP 2xx to both POST and HEAD during setup
validation_field: thrivecart_secret
events:
- order.success
- order.refund
- cart.abandoned
- order.subscription_payment
- order.subscription_cancelled
- order.subscription_paused
- order.subscription_resumed
- order.rebill_failed
- affiliate.commission_earned
- affiliate.commission_payout
- affiliate.commission_refund
- customer_updated
x-gaps:
- ThriveCart publishes no AsyncAPI, no JSON Schema and no field-level payload reference for any
event. Only the delivery envelope fields are documented, so a consumer must observe a live
delivery to learn the shape.
- Deliveries are not signed. Authenticity depends on a static secret echoed in the body, with no
HMAC, no timestamp and no replay window.
- Retry behaviour is acknowledged ("if we retry the same delivery") but no schedule, backoff or
maximum attempt count is published, and there is no delivery log or replay endpoint.
- The two event surfaces use different names for the same underlying facts (order_created vs
order.success), which is a standing source of integration error.
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.