Plan changes in a pricing plan group
Move a subscription from one plan to another in the same pricing plan group in a single call, with the timing decided by the group rather than by the caller.
Why this matters
An upgrade from Starter to Pro is one commercial decision. As a billing operation it is several: end the running schedule on the right date, open a new one on the target plan, keep the currency and billing period, and get the pro-ration right. Doing that by hand means the same sequence of calls every time. The date it lands on is then whatever the caller passed, rather than what the plan family says it should be.
A pricing plan group already holds that policy: which plans belong together, in what order, and when a move between them takes effect. change-plan executes it. An upgrade becomes one request, and the timing rules live with the plans instead of in your integration.
How it works
A group carries an ordered list of member plans and three transition policies:
The move itself is a new schedule on the same subscription, pointing at the target plan. The schedule that was running is closed at the moment the new one starts, so the subscription still has exactly one schedule in effect.
Direction is inferred, never passed. A target with a higher order than the current plan is an upgrade and follows upgrade_type; a lower one is a downgrade and follows downgrade_type. That policy then resolves the date:
IMMEDIATE and IMMEDIATE_PRO_RATA resolve to the same start moment. What follows from that start is the subscription’s own pro-ration behaviour: whether the closed period is charged in full or pro-rated. The two policies describe that behaviour rather than change it.
Change the plan
Send the target plan. Everything else is either inferred or carried over:
The response is the new schedule, returned with 201 Created. See Change the pricing plan of a subscription in the API reference. The call needs both PRICING_PLAN_SUBSCRIPTION.UPDATE and PRICING_PLAN_SCHEDULE.CREATE, since it updates a subscription by creating a schedule on it.
What the new schedule takes with it
Anything negotiated onto the schedule being replaced is customer-specific pricing on a plan the customer is leaving. It is not copied onto the plan they are moving to. Configure it again on the new schedule if it still applies.
A target plan that is a rate card works the same way. The version applicable at the new schedule’s start is resolved, and the schedule keeps following the rate card rather than being pinned to that version.
Change only the billing period
A plan sold in several billing periods, monthly and yearly against the same pricing, is moved between them by sending the plan the subscription is already on together with a different billing_period:
There is no order difference to read the direction from here, so it comes from the length of the period instead. A longer billing period is an upgrade, a shorter one a downgrade. The group’s policy for that direction then decides the timing as usual. Two periods of the same length, MONTH/12 against YEAR/1, carry no direction and are rejected.
Show the group in the customer portal
A self-service upgrade screen has to know which plans it may offer. That is exactly the group’s member list, and the portal exposes it for the subscription the session is scoped to:
The response is the group itself. It carries the members with their order, plus the upgrade_type, downgrade_type and cancellation_type. Those tell the screen which moves are possible, and when each would take effect.
The portal endpoint is read-only. Performing the change is a platform-side call, so the customer’s action reaches change-plan through your backend, not from the browser. For the changes a customer can make to their own subscription directly, see Self-serve plan changes.
What is rejected
Via Desk
There is no dedicated plan change action in Desk yet. An agent making the same move edits the subscription’s schedules directly, which the group’s policies do not bind. The policies exist to keep an automated or self-service change on the terms the plan family was sold on.
Edge cases
- The move is not a migration. Migrating a schedule moves it to a different version of the plan it is already on.
change-planmoves the subscription to a different plan. That is why it builds a new schedule instead of remapping the existing one. start_atcannot be in the past. The subscription also has to be active at that moment, so a date before its start is rejected.- Only billing subscriptions. A quote subscription is rejected: agreed terms change through a new quote version, not through this action.
- The group is resolved from the current plan, not from the request. If the subscription’s plan was removed from its group, the call fails. It does not fall back to the target’s group.