ThriveCart · AsyncAPI Specification

ThriveCart Event Subscriptions

Version 1

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 Spec View on GitHub CompanyCheckoutShopping 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.

AsyncAPI Specification

Raw ↑
# 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.

Work with this as data

Every AsyncAPI spec here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for asyncapi

4 MCP tools reach this
  • find_asyncapisBrowse and filter every AsyncAPI spec in the catalog.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This AsyncAPI spec
curl "https://apis.io/api/v1/asyncapis/thrivecart-events-asyncapi"
All asyncapi
curl "https://apis.io/api/v1/asyncapis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no email required.

A second provider on the same verified email joins the account you already have.