Create a subscription
Use checkout for payment-gated plans. Direct subscription creation is available for flows that do not require interactive payment.404 customer_not_found and creates nothing.
subscribe creates the subscription sub-<customer_id>-<plan_code>; calling it again for the same plan returns that subscription and creates nothing. Calling it for a customer who already has a subscription to a different plan adds a second active subscription; it does not replace the first, and plan credit grants are granted again. After that, tracking without an explicit subscription ID fails because the customer has two. To move a customer to another plan, change the existing subscription through checkout with its subscription_id, or cancel it with immediate timing and then subscribe. Pass the new subscription ID to track: the Node.js and Python clients cache the subscription they resolved first.
subscribe does not collect payment, even for a paid plan. Use checkout when payment must succeed first.
Customer self-service
Use the native React billing portal, or addCancellationControl and PlanChangeControl to your own billing page. Your authenticated Node.js, Python, or Go backend supplies their action adapters.
The matching hosted API is available. Use React
0.10.2 with Node 0.10.0, Python 0.10.0, or Go v0.9.1, or later; the portal guide provides setup and integration examples.
Select, preview and confirm
A customer may have multiple subscriptions. Use its external subscription ID on every management call. Plan changes follow a plan transition policy that you configure for each pair of plans. Without one, preview and checkout return422 plan_transition_policy_required; the only fallback is the organization’s free-to-paid policy, used from a free plan to a paid plan. Check eligibility through subscription options; do not infer it from price or catalog membership.
The Node subscriptionOptions, Python subscription_options, and Go SubscriptionOptions methods return current, pending and eligible plans. Their previewSubscriptionChange, preview_subscription_change, and PreviewSubscriptionChange methods return an opaque signed quote with exact minor-unit amounts, currency, effective date and renewal date.
After customer confirmation, pass the quote and a stable idempotency key to checkout for upgrades. For scheduled downgrades, use the existing transition API with end-of-period timing and keep_anchor. A quote is valid for five minutes and binds the subscription state, plan versions, policy and amounts. A changed quote returns HTTP 409 and requires a fresh confirmation.
Preserve the same key, quote and payload when retrying one confirmed action after an uncertain response. Replaying an accepted action can succeed after quote expiry. Save merchant retry context durably; do not generate another collection attempt merely because a browser callback was lost.
Payment and reload behavior
The current paid plan remains active until required payment is fulfilled. Razorpay requires capture; Stripe requires backend settlement. A browser callback or redirect alone does not establish activation. Reload authoritative state after checkout, failures and page reloads, and resume a recoverable checkout using its existing ID. Treat processing, expiry and support review as separate states. Scheduled downgrades keep a distinct pending plan/effective date. Withdrawal uses its exact internal pending UUID, whereas ordinary management calls use the active subscription’s external ID. A stale withdrawal cannot remove a replacement pending change. See Node billing, Python billing, Go billing, and the HTTP contract for signatures and examples.Simple cancellation
The Node.js, Python, and Go SDKs default to end-of-period cancellation:immediate explicitly only after the merchant confirms that access should end now. For customer-facing Cancel/Keep, use the transition preview/apply flow and forward the exact expectedEffectiveAt / expected_effective_at / Go ExpectedEffectiveAt timestamp. Keep does not restart an ended subscription. Cancellation removes a pending downgrade; Keep does not recreate it.
Settlement transitions
The backend SDKs provide preview and apply operations forcancel, downgrade, and uncancel.
- timing:
end_of_periodorimmediate; - billing anchor:
keep_anchororreset_anchor; - proration:
prorate_immediatelyornone; - credit action:
credit,refund,offset, ornone; - refund mode:
proratedorfull; and - final invoice:
generateorskip.
creditAction: 'none'; uncancel does not accept settlement options.
Enforce access in your application
The portal changes billing state; your application enforces feature access using Nozle entitlement checks. The hosted Engine reads the current subscription and database clock for/can, denying access at its saved ending even if the termination job has not yet updated the row. Keep is visible after commit without waiting for the old subscription-cache refresh.