Skip to main content
When you add or remove features on a plan, existing active subscriptions do not automatically pick up the change — their entitlements stay as they were at activation. Reconciliation converges an active subscription’s feature entitlements to the prices that subscription bills, in a single call: it provisions missing features, removes features for prices the subscription no longer bills, and synchronizes the corresponding billing. Most subscriptions bill their plan’s current prices, so reconciliation converges them to the plan’s current shape. A subscription pinned to a specific plan version bills that version’s prices instead, and reconciliation converges it to that version, not to the plan’s current default. Throughout this page, “the prices the subscription bills” means the prices on the subscription’s billing record at the moment of the call. For a subscription that follows the plan’s current version, reconciliation also targets the features of the prices in that current version. Those prices start to bill in the next period, not the current one, and their features start at the same instant. Some prices grant a feature but produce no line item — a credit-denominated price, or an already-elapsed one-time charge. Reconciliation still keeps or provisions their entitlements, and reports them with billed: false.

When to use it

Reach for reconciliation whenever a plan’s feature list drifts from what an existing active subscription actually has:
  • You added a feature to a plan and want existing subscribers to get it without recreating the subscription.
  • You removed a feature from a plan and want to stop billing existing subscribers for it and revoke their entitlement.
  • A prior subscription activation partially failed and left the subscription without one of the plan’s features.
  • You want to preview either of the above without touching billing — use dryRun: true.
You do not need reconciliation when the plan and subscription are already aligned. New subscriptions provision entitlements automatically at activation; see Automatic entitlement provisioning.

What reconciliation does

A reconciliation is a single, idempotent operation that:
  1. Adds an entitlement (and, for metered features, its initial grant) for every feature of a price the subscription bills but is missing.
  2. Removes the entitlement and voids the grants of any feature the subscription no longer bills.
  3. Skips features that are already present — they are left unchanged.
  4. Synchronizes billing by creating future line items for added prices and removing future, uninvoiced line items for removed prices.
Reconciliation mints metered feature grants as full-period grants and does not prorate for the current period. Reconciliation never modifies already-invoiced line items — it only touches future, uninvoiced periods.

Timing of a removed feature

A subscription keeps billing a price for the rest of the period it has already paid for, even after that price drops off the plan. Reconciliation does not remove the feature’s entitlement until the subscription’s own billing record for that price closes, at the end of that period. Until then, the feature stays active and is not reported as removed. Run reconciliation again after that period ends to remove the entitlement.

Timing of an added feature

This applies to a subscription that follows the plan’s current version. Reconciliation moves the subscription to the current version. The plan’s versionTransition decides when the feature starts. With end_of_current_period, the default, the feature starts at the start of the subscription’s next period, when its recurring price starts to bill. The move creates the entitlement with activeFrom at the next period start and, for a metered feature, a grant that starts at the same instant. The customer has no access to the feature before then. The entitlement already exists when reconciliation compares the features, so the response reports the feature in skipped, not in added. Reconciliation creates no line item for the current period. A credit-denominated price and an already-elapsed one-time charge never bill, but their feature also starts at the next period. Usage of a metered feature before its price starts to bill is not billed. With immediate, the move starts the feature at the reconciliation, with its full grant, and the response reports it in added. A feature that the version drops ends at the reconciliation and is reported in removed. The prices follow the rules of an immediate move. If the next billing run moved the subscription before you reconcile, the feature already has its entitlement, and the response reports it in skipped. A dryRun reports the same added feature and writes nothing: no entitlement, grant, price interval or line item. A subscription pinned to its own version does not take the new price at all. It takes a price only if the version it holds carries that price.

Making a reconciliation request

API Reference: See the Reconcile Features API endpoint for the complete request and response schema.
Send an empty body (or { "dryRun": false }) to a subscription’s reconciliation endpoint. The subscription must be active.

Previewing with dry run

Pass dryRun: true to compute the same diff without creating any entitlement, grant, or line item. The response is shaped identically to a real run and reports exactly what a subsequent real call would do. Use it to confirm the scope of a change before applying it.

Response

The response returns a subscriptionReconciliation object describing the outcome:

Feature groups

  • added — Features the subscription was missing that were provisioned. A billed: false entry means the feature’s price does not produce a recurring line item, so the feature is entitled but not billed by this reconciliation. Examples include a credit-denominated price or an already-elapsed one-time charge.
  • skipped — Features the subscription already had an active entitlement for. Left unchanged. This includes a feature that a move to the plan’s current version starts at the next period, and a feature that an earlier immediate move started.
  • removed — Features for a price the subscription no longer bills. Their entitlement was canceled and grants voided so the subscription matches the prices it currently bills. A feature for a dropped price is not reported here until the subscription’s billing record for that price closes.
  • failed — Features that could not be fully provisioned. Never billed by this call. Each entry has a coded reason:
    • entitlement_failed — the entitlement itself could not be created.
    • grant_mint_failed — the entitlement was created but its initial metered grant could not be minted. Re-running reconciliation retries the mint safely.

Line items

  • created — Number of features newly billed on the subscription by this reconciliation. A dry-run preview returns the same count as the applied run.
  • removed — Number of features whose billing was removed from the subscription’s upcoming (not-yet-invoiced) invoice because their price is no longer on the plan.
  • syncFailed — Present and true when entitlements were provisioned successfully but the line-item synchronization step failed. Safe to retry.

Status codes

Error codes

  • SUBSCRIPTION_NOT_ACTIVE — The subscription is not in the active state. Reconciliation is only available for active subscriptions.
  • SUBSCRIPTION_NOT_V1_BILLING — The subscription is on Legacy Billing (billingVersion: 0). Reconciliation only applies to Standard Billing subscriptions.
  • SUBSCRIPTION_TIMELINE_RESOLUTION_FAILED — Paygentic could not read the subscription’s billing record. Nothing changed. Retry after the delay in the retry-after header.

Idempotency and retries

Reconciliation is safe to retry:
  • The API detects already-provisioned entitlements and grants and does not duplicate them.
  • If a previous run created an entitlement but failed to mint its initial metered grant, re-running reconciliation retries the mint on the same idempotency key. The mint is a no-op when the grant is already present.
  • If a run returns 200 with lineItems.syncFailed: true, retry to complete billing synchronization.
  • A 503 with SUBSCRIPTION_TIMELINE_RESOLUTION_FAILED changes nothing, so a retry is always safe.

Rate limits

Reconciliations are limited to 2 requests per second per subscription. Each subscription has its own allowance, so a loop over many subscriptions is not limited in total. A 429 Too Many Requests response returns the retry-after header. Wait for that number of seconds before you send the request again. See Rate limits for the buckets, the response headers, and the retry rules.