Why a subscription fixed charge shows future units after an update with apply_units_immediately false

Last updated: July 13, 2026

After updating a fixed charge's units on a subscription with apply_units_immediately: false, the subscription fixed charge endpoint (GET /api/v1/subscriptions/{external_id}/fixed_charges/{code}) returns the new units right away, even though billing does not change until the next period. The response always reflects the latest requested units, not the units currently being billed. To read the currently paid-for units, use the fees API instead.

How fixed charge units updates work

Updating units on a subscription's fixed charge does two things. It immediately stores the new units value for that subscription, which is what the fixed charge endpoint returns from then on. Separately, it records when the change takes billing effect: with apply_units_immediately: true the change applies from the moment of the update, and with false it applies from the start of the next billing period. (The mechanics of how these two records are stored are an implementation detail and may change.)

This means the endpoint's units field is the target state. After reducing seats mid-period with apply_units_immediately: false, it shows the reduced count while the customer remains billed, and entitled to, the old count through the end of the period.

For pay-in-advance fixed charges, billing also only ever charges the delta above what has already been billed in the period. Verified behavior on a monthly pay-in-advance prorated seat charge:

  • 5 seats billed, then reduced to 3 with apply_units_immediately: false: no new invoice, the 5 seats stay paid through period end.

  • Increased back to 5 with apply_units_immediately: true: a zero-amount fee, nothing charged, because those seats were already paid for.

  • Increased to 7 with apply_units_immediately: true: only the 2 new seats are billed, prorated for the remainder of the period.

How to read the currently paid-for units

For pay-in-advance fixed charges, the units already billed for the current period are on the fixed charge fees, not the fixed charge object. List them with:

GET /api/v1/fees?fee_type=fixed_charge&external_subscription_id={sub_id}&created_at_from={billing_period_start}

Sum units across the returned fees to get the capacity paid for through the end of the period. Mid-period increases appear as additional fees (including zero-unit fees when the change stays within already-paid capacity), so the sum stays correct.

This makes entitlement logic straightforward: an action incurs a new charge only if it pushes units above the sum of current-period fixed charge fee units. Seats freed by a non-immediate decrease remain paid for, and can be reassigned at no cost, until the period rolls over.

Caveats:

  • created_at_from should be the subscription's current billing period start (current_billing_period_started_at on the subscription object). Compute it per subscription, since calendar and anniversary billing differ.

  • Each fee also carries from_date and to_date period boundaries. These are the authoritative period fields; created_at filtering works for pay-in-advance fixed charges because their fees are created at or after period start, but a pay-in-arrears fixed charge fee for the previous period would be created at the current period's billing run and would be miscounted by a created_at filter alone.

  • Fees on voided invoices still appear in the list, and payment_status (pending, succeeded, failed, refunded) tracks actual payment separately from billing. Check lago_invoice_id and payment_status if voids or failed payments matter to the entitlement decision.

  • This approach only applies to pay-in-advance fixed charges. A pay-in-arrears fixed charge has no fee until the period ends, so there is nothing to sum mid-period.


This article reflects guidance drawn from customer case resolutions. It is not officially supported documentation and may not apply to all situations.