Change flows
A subscription changes through a set of flows. Today most are queued from the UI — the LedgerBee operator app and the customer portal — and the public API reads and cancels queued changes but does not create them. The exceptions are cancellation and billing-group membership, which have public endpoints. (A public "queue a change" API is planned.)
| Flow | What it does | Activates | Where today |
|---|---|---|---|
| Replace plan | Swaps the plan; settles any overlap | at the next billing boundary | UI |
| Direction change | Switches advance ⇄ arrears | next boundary | UI |
| Cadence change | Switches among the plan's alternative cadences | next boundary (doesn't stack) | UI |
| Products edit | Changes the product set / quantities → new segment | next boundary | UI |
| Pause / resume | Suspends billing, then resumes | immediately / on resume date | UI |
| Cancel / churn | Ends the subscription | per strategy (below) | Public API + UI |
| Form a billing group | Bills several of one customer's subscriptions on one shared invoice | the lead's next billing date | Public API + UI |
| Join a billing group | Adds a subscription to an existing group's shared invoice | the group's next billing date | Public API + UI |
| Leave a billing group | Returns a subscription to its own invoice | at once; bills alone from its next billing date | Public API + UI |
Each flow appends a version or segment. A plan
replacement or products edit re-bills the affected partial period and carries its
own prorationBehavior to settle it. A queued,
not-yet-active flow is a scheduled change you can read or cancel over the API
(below).
Cancel
POST /v1/subscriptions/cancel is the one change flow with a public endpoint:
Code
| Strategy | Effect |
|---|---|
end_of_cycle | Cancels at the end of the current billing period. |
immediately | Cancels now; optionally set refundBehavior (below). |
specific_date | Cancels on effectiveDate (required for this strategy). |
clear_schedule | Removes a previously scheduled cancellation, leaving it running. |
An immediate cancel can issue a refund via refundBehavior:
| refundBehavior | Behavior |
|---|---|
none | No refund is issued. |
last_invoice | Refund the full amount of the last paid invoice. |
prorated | Refund the prorated amount for unused time since the last invoice. |
On a subscription that bills on a
billing group, last_invoice is refused
with 400 SUBSCRIPTION_BILLING_GROUP_REFUND_LAST_INVOICE_NOT_SUPPORTED: the last
paid invoice is the group's and covers other subscriptions. Use prorated or
none. Cancelling a group member ends that member; the other members keep
billing on the group. The cancellation can still answer
SUBSCRIPTION_BILLING_GROUP_CANCEL_BLOCKED_BY_MEMBER (another member's state
blocks it; details.blockingSubscriptionId names it),
SUBSCRIPTION_BILLING_GROUP_MEMBERSHIP_CHANGED (the group changed while the
request ran; nothing was changed, retry) or
SUBSCRIPTION_BILLING_GROUP_CANCEL_REFUND_SPANS_INVOICES (the refund would
credit more than one invoice; cancel without a refund or cancel the members
separately).
A scheduled cancellation (end_of_cycle / specific_date) is itself a queued
change — clear it before it activates with clear_schedule or via
scheduled-changes below.
Read or cancel a queued change
A queued plan replacement, products edit, direction change, or future cancellation is a scheduled change that hasn't activated. List them:
Code
Code
kind is one of replace_plan, edit_products, change_direction, or churn.
Cancel one by its changeId (DELETE …/scheduled-changes/{changeId}); the rest
of the subscription is unaffected and the response is the current state.
changeId is ephemeral — valid only until the change activates or is
cancelled. Always re-list rather than caching it.