LedgerBee Developer
  • Getting started
  • Conventions
  • Products
  • Advisor firms
  • Configuration
  • API Reference
Subscriptions
    OverviewAssign a subscriptionData modelLifecycle & statusesBilling & cadenceProrationUsage commitmentsReporting usageMonthly revenue & unbilled usageChange flowsParent & childAdd-onsBilling groupsWebhooks
Payment flowCard paymentsProducts & PricingDiscountsProduct Entitlements
Billing documents
Accounting
WebhooksPartner-Hosted Checkout
Customer Portal
Subscriptions

Webhooks & reconciliation

Subscribe to subscription events to react to lifecycle changes and reconcile them against your own records. See Webhooks for endpoint setup, the signed-envelope format, signature verification, and retries; this page covers the subscription topics and how to reconcile them.

Topics

TopicFires when
subscription.assignedFired when a subscription is assigned to a customer (may be future-dated / upcoming).
subscription.startedFired when a subscription becomes active — grant entitlement/access on this event, not on assigned.
subscription.updatedFired when a config property changes without a structural transition (e.g. name, payment method, billing direction).
subscription.transitionedFired on a structural change: plan replace, product edit, billing cadence change, phase change, or realign.
subscription.pausedFired when a subscription is paused.
subscription.resumedFired when a subscription resumes from a pause.
subscription.trial_endedFired when a subscription trial ends. The payload outcome says whether billing begins (ACTIVE) or the subscription was held for a missing payment card (PAUSED).
subscription.cancellation_scheduledFired when a future cancellation is scheduled for a subscription (still active until then).
subscription.cancellation_clearedFired when a previously scheduled cancellation is cleared.
subscription.churnedFired when a subscription is cancelled/finalized — revoke entitlement on this event.
subscription.billedFired once per subscription that billed onto an invoice — one per child on a parent-paid consolidated invoice, one per member on a billing-group invoice. amount is always the whole document total; deduplicate on invoiceId, attribute on billingGroupId, never sum amount across events.
subscription.billing_heldFired when a billing run holds an invoice instead of issuing it, because it is below the minimum invoice amount or below the smallest amount the subscription's card can be charged: nothing is invoiced or charged, and the held periods are added to the subscription's next invoice. One event per subscription with a period on the held invoice.
subscription.payment_succeededFired when a card charge for the subscription clears — the success pair of the charge_failed error signal. On a billing-group card charge one event fires per member, each carrying the full charged amount and the shared billingGroupId.
subscription.errorFired when a delivery/processing problem occurs for a subscription (e.g. undeliverable recipient).

Entitlement synchronization

Access-boundary payloads include entitlementIds. Grant or replace access when the subscription starts, transitions, resumes, or ends its trial. An assigned event is advance notice and can describe a future start. Revoke access on an effective pause or finalized cancellation. Both carry an empty array.

Do not infer access from billing or payment topics. Reconcile a missed event by reading the subscription detail endpoint. See Product Entitlements for the identifier and ownership contract.

subscription.error

The subscription.error topic reports a billing problem rather than a lifecycle change.

The errorType field discriminates which problem occurred — it is one of:

errorTypeMeaning
recipient_undeliverableA document recipient for the subscription is undeliverable (e.g. the email hard-bounced); the document was not delivered.
charge_failedA card charge (first or recurring) for the subscription failed. Automatic retries continue across the grace window, and this fires on each decline. The raw provider decline is not exposed on the payload.
dunning_exhaustedAutomatic card-charge retries for the subscription are exhausted after the grace window; no further automatic attempts will be made and the outstanding invoice becomes collectible. Fires once per subscription, distinct from the per-decline charge_failed — a billing group emits one per member, each naming that member, so "once per subscription" holds on both rails.

Price changes

The started and transitioned events carry monthlyRevenue and currency. A transition scheduled for a later date is sent when it is made, with effectiveDate set to the day it takes effect, and a phase_changed transition follows on that day when the monthly revenue or the entitlements change. What the figure includes is described in Monthly revenue & unbilled usage.

Reconcile on the stable id

Every subscription.* event carries the stable id as data.subscriptionId, plus data.partnerReferenceId and a diagnostics-only data.versionId. Reconcile on subscriptionId or partnerReferenceId, never versionId — the version id changes on every structural change (see Data model).

partnerReferenceId is the clientReferenceId you pass when binding an embedded checkout — your join key for matching a subscription to your own order.

Recover a lost event

If a delivery is lost, recover the join over the API by your own reference:

TerminalCode
curl "https://api.ledgerbee.com/api/v1/subscriptions?partnerReferenceId=order_42" \ -H "x-api-key: YOUR_API_KEY"

One invoice, several events

An invoice can carry more than one subscription: a parent that pays for its children on one consolidated invoice, or a billing group whose members share one document. Such an invoice produces one subscription.billed per subscription on it. Every one of those events carries the same invoiceId and invoiceNumber, and every one carries the whole document total as amount, never that subscription's share. Deduplicate on invoiceId, and never sum amount across events for the same invoice.

billingGroupId on the billed and payment-succeeded events, and on the billing document events, names the set the document belongs to. It is null on a subscription's own document. When the group pays by card, each member receives the payment-succeeded event when the group's charge clears, and the exhausted-retries error if it never does. Gate a member's access on those two: the per-decline charge error is never raised for a member, and a member never enters awaiting_payment.

Held billing periods

A billing run that holds an invoice below your minimum invoice amount, or below the smallest amount the subscription's card can be charged, issues no invoice and charges nothing. It emits the billing-held event instead (see Topics): one per subscription with a period on the held invoice, staged in the same transaction as the hold. Its payload names:

  • heldPeriods: the periods this hold kept off an invoice, each as periodStart and an exclusive periodEnd
  • reason: below_minimum_invoice_amount or below_card_minimum
  • heldAmount and currency: what the held invoice came to including VAT, with minimumAmount and minimumCurrency for the minimum it was below
  • heldPeriodCount and maxPeriodsOnOneInvoice: how many of the subscription's periods are on hold now, and the most one invoice covers
  • nextBillingDate: the billing date of the invoice the held periods are added to, which can itself be held if it is below the minimum too
  • invoicedByDate: the latest billing date on which they are invoiced whatever the total comes to

The invoice that later carries the periods fires subscription.billed as usual, and its heldPeriods lists this subscription's earlier-held periods that the invoice now covers. The array is empty on an invoice that carries none. When the document carrying held periods nets negative, they go out on a credit note instead, and the credit-note-sent billing event lists them in its own heldPeriods. Full payloads are under Event types.

Match the periods you recorded from billing-held events against the heldPeriods of the later billed or credit-note-sent event. While a period is held, nextBillingDate has moved on and paidThroughDate has not; see Held billing periods.

Last modified on November 6, 2026
Billing groupsPayment flow
On this page
  • Topics
  • Entitlement synchronization
  • subscription.error
  • Price changes
  • Reconcile on the stable id
  • Recover a lost event
  • One invoice, several events
  • Held billing periods