Skip to main content

Change Subscription Plan

Switch a subscription to a different variant of the same product.

The change is transactional and prorated. The proration is invoiced immediately, and the new plan takes effect as soon as it is paid. If the proration payment is declined, the plan change does not take effect and the call returns 422 with the decline reason.

Validation rules

The endpoint rejects the request with 422 when the target variant fails any of these checks:

ReasonError message
Target variant does not exist or does not belong to your storeTarget variant not found.
Target variant is attached to a different productTarget variant does not belong to the subscription's product.
Target variant is one-time (not recurring)Target variant must be recurring.
Target variant is the variant the subscription is already onSubscription is already on the requested variant.

Request

POST /subscriptions/{id}/change-plan

Path Parameters

ParameterTypeRequiredDescription
idstringYesSubscription UUID

Request Body

ParameterTypeRequiredDescription
variant_idstringYesTarget variant (price) UUID

Example Request

curl -X POST "https://cart.easy.tools/api/v1/subscriptions/550e8400-e29b-41d4-a716-446655440040/change-plan" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"variant_id": "550e8400-e29b-41d4-a716-446655440002"
}'

Response

Success Response (200)

Returns the updated subscription (base fields only; no include sections) — the variant_name, recurring_amount, interval, etc. reflect the new plan.

{
"id": "550e8400-e29b-41d4-a716-446655440040",
"remote_id": "sub_1QabcDEFghiJKLmn",
"provider": "stripe",
"status": "active",
"variant_name": "Annual Plan",
"product_name": "Premium Course",
"recurring_amount": 49000,
"currency": "pln",
"interval": "year",
"interval_count": 1,
"quantity": 1,
"customer_email": "buyer@example.com",
"current_period_start": "2026-05-28T12:00:00+00:00",
"current_period_end": "2027-05-28T12:00:00+00:00",
"trial_end": null,
"cancel_at": null,
"canceled_at": null,
"active_until": null,
"active_cycles": null,
"cancel_early": false,
"keep_access_after_expiring": false,
"is_delegated": false,
"is_cancelable": true,
"created_at": "2026-01-15T10:00:00+00:00",
"customer": null,
"variant": null,
"product": null,
"order": null,
"renewals": null,
"upcoming_invoice": null
}

See the Get Subscription reference for a full description of each base field.

Error Responses

Bad Request (400)

Returned when the path parameter or variant_id is not a valid UUID.

{
"message": "Invalid subscription ID"
}
{
"message": "Invalid variant ID"
}

Subscription Not Found (404)

{
"message": "Subscription with ID 550e8400-e29b-41d4-a716-446655440040 not found"
}

Validation Error (422) — request body

Returned when variant_id is missing or malformed.

{
"message": "The given data was invalid.",
"errors": {
"variant_id": [
"The variant_id field is required."
]
}
}

Variant Rejected (422)

Returned when the target variant fails one of the validation rules.

{
"message": "Target variant does not belong to the subscription's product."
}
{
"message": "Target variant must be recurring."
}
{
"message": "Subscription is already on the requested variant."
}

Provider Error (422)

Returned when the payment provider rejects the plan change.

{
"message": "Payment provider rejected the plan change: <provider message>"
}

Payment Failed (422)

Returned when the proration payment is declined. The plan change has not taken effect. The message carries the decline reason; when the provider gives no specific reason, it reads The proration payment could not be completed.

{
"message": "Your card was declined."
}

Unauthorized (401)

{
"message": "Unauthenticated."
}