Downgrade a Subscription Effective Next Billing Date

Overview

This guide shows you how to implement the Update Subscription Item endpoint to allow a customer to downgrade a subscription effective on the next billing date.

Use case

  1. A Cloudify customer currently on the Cloudify Bronze plan wants to switch to a cheaper plan, Cloudify Iron.
  2. They navigate to the Edit My Subscription page. The Get Subscription endpoint is used to obtain the customer's current subscription details.
  3. The customer chooses a cheaper plan, Cloudify Iron, effective on the next billing date. The Update Subscription Item endpoint is used to update the subscription details in the Cleverbridge platform.

Result

The Cleverbridge platform automatically bills the customer $9.99 on the next billing date.

Implement the Update Subscription Item endpoint

Before you start

Make sure that:

  • The subscription has the status Active.

  • The product to which the customer wants to downgrade has been set up in the Cleverbridge platform.


🚧

Important

Get the customer's consent before making changes to a subscription.

To avoid chargebacks and customer inquiries, it is also essential that you coordinate all price increases with Client Experience.

In the European Economic Area (EEA), Strong Customer Authentication (SCA) is required for recurring electronic payments when the amount changes. This means that some of your customers will have to authenticate their payment, which in turn might impact the renewal success rate.

For more information, see Best Practices: Obtain Customer Consent.

Step 1: Get the customer's current subscription details

Parameters

Parameter

Type

Required

Example

Notes

SubscriptionId

str

Yes

S67645948

The unique identifier of the subscription.
Maps internally to the numeric subscription ID returned in the response payload.

Request

curl --location 'https://rest.cleverbridge.com/subscription/getsubscription?subscriptionId=S67645948' 
--header 'Accept: application/json' 
--header 'Authorization: Basic YOUR_BASE64_ENCODED_CREDENTIALS' 
import http.client

conn = http.client.HTTPSConnection("rest.cleverbridge.com")
payload = ''
headers = {
  'Accept': 'application/json',
  'Authorization': 'Basic YOUR_BASE64_ENCODED_CREDENTIALS'
}
conn.request("GET", "/subscription/getsubscription?subscriptionId=S67645948", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
var https = require('follow-redirects').https;
var fs = require('fs');

var options = {
  'method': 'GET',
  'hostname': 'rest.cleverbridge.com',
  'path': '/subscription/getsubscription?subscriptionId=S67645948',
  'headers': {
    'Accept': 'application/json',
    'Authorization': 'Basic YOUR_BASE64_ENCODED_CREDENTIALS'
  },
  'maxRedirects': 20
};

var req = https.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function (chunk) {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });

  res.on("error", function (error) {
    console.error(error);
  });
});

req.end();
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.get("https://rest.cleverbridge.com/subscription/getsubscription?subscriptionId=S67645948")
  .header("Accept", "application/json")
  .header("Authorization", "Basic YOUR_BASE64_ENCODED_CREDENTIALS")
  .asString();

Response

{
    "Subscription": {
        "CustomerCurrencyId": "USD",
        "CustomerId": 157128091,
        "CustomerReferenceId": "5xHHFS1lQV3ry0zoFgWxL9EcqYKEsYgA6g0ztZqo",
        "CustomerReferenceNo": "",
        "EndDate": null,
        "GracePeriodDays": 0,
        "Id": 67204221,
        "IntervalDayCount": 0,
        "IntervalMonthCount": 6,
        "BillingIntervalDayCount": 0,
        "BillingIntervalMonthCount": 0,
        "Items": [
            {
                "Couponcode": "",
                "DeactivationDate": null,
                "EndDate": null,
                "IsCurrent": true,
                "LastIntervalNo": 1,
                "NextBillingCurrencyId": "USD",
                "NextBillingCustomerGrossPrice": 35.64,
                "NextBillingCustomerNetPrice": 29.95,
                "NextBillingCustomerVatPrice": 5.69,
                "NextRenewalCustomerGrossPrice": 35.64,
                "NextRenewalCustomerNetPrice": 29.95,
                "NextRenewalCustomerVatPrice": 5.69,
                "ProductId": 292124,
                "ProductName": "Cloudify Bronze",
                "ProductNameExtension": "Cloud Storage",
                "PromotionId": null,
                "Quantity": 1,
                "RecurrenceCount": null,
                "RunningNo": 1,
                "StartDate": "2026-01-19T10:10:56.38897",
                "Status": 1,
                "SubscriptionId": 67204221,
                "SubscriptionPurchaseItems": [
                    {
                        "PurchaseId": 528826307,
                        "PurchaseItemRunningNo": 1,
                        "SubscriptionIntervalNo": 0,
                        "BillingIntervalNo": 0
                    },
                    {
                        "PurchaseId": 537703779,
                        "PurchaseItemRunningNo": 1,
                        "SubscriptionIntervalNo": 1,
                        "BillingIntervalNo": 0
                    }
                ],
                "Version": 1,
                "VersionActiveDate": "2026-01-19T10:10:56.38897"
            }
        ],
        "LastIntervalNo": 1,
        "LastBillingIntervalNo": 0,
        "NextBillingCurrencyId": "USD",
        "NextBillingCustomerGrossPrice": 35.64,
        "NextBillingCustomerNetPrice": 29.95,
        "NextBillingCustomerVatPrice": 5.69,
        "NextRenewalCustomerGrossPrice": 35.64,
        "NextRenewalCustomerNetPrice": 29.95,
        "NextRenewalCustomerVatPrice": 5.69,
        "NextBillingDate": "2026-10-12T23:36:58.625295",
        "NextRenewalDate": "2026-10-12T23:36:58.625295",
        "NextBillingDateReminder": "2026-10-10T23:36:58.625295Z",
        "PaymentInfo": {
            "CardExpirationDate": {
                "Month": 11,
                "Year": 2027
            },
            "CardLastFourDigits": "765T",
            "Currency": null,
            "CurrencyId": null,
            "IsPurchaseOrder": null,
            "PaymentType": "Visa",
            "PaymentTypeId": "CCA_VIS"
        },
        "RenewalType": "Automatic",
        "StartDate": "2026-01-19T10:10:56.38897",
        "StartIntervalDayCount": 0,
        "StartIntervalMonthCount": 1,
        "Subscriptionstatus": 1,
        "ManagementModel": "One",
        "SelfServiceUrl": "https://www.cleverbridge.com/864/s/s67204221-FRGGMiD8Psv8MIjA"
    },
    "ResultMessage": "OK"
}

Step 2: Downgrade using Update Subscription Item endpoint

Parameters

Parameter

Type

Required

Example

Notes

AlignmentSettings

obj

No

AlignToCurrentInterval: false

GetCustomerPricePreviewOnly: false

The subscription is changed as requested in the API call.

ProductId

int

Yes

294597

Product ID for the new, cheaper product (Cloudify Iron).

RunningNumber

int

Yes

1

Running number of the item in the subscription.
Use the RunningNo value returned by the Get Subscription response.

Quantity

int

Yes

1

Total number of items after the update.

SubscriptionId

str

Yes

S67645948

The unique identifier of the subscription.

UpdateAction

str

No

downgrade

The value set does not affect transaction processing.
See the note below.


📘

Note

The UpdateAction parameter is currently used for documentation and tracking only. The value set does not affect transaction processing.

The supported values are as follows:

  • For upgrades, set the parameter to upgrade (or 1 for JSON)
  • For downgrades, set the parameter to downgrade, (or 2 for JSON)
  • For all other changes, set the parameter to update (or 0 for JSON)

Request

curl --location 'https://rest.cleverbridge.com/subscription/updatesubscriptionitem' 
--header 'Content-Type: application/json' 
--header 'Accept: application/json' 
--header 'Authorization: Basic YOUR_BASE64_ENCODED_CREDENTIALS'
--data '{
  "ProductId": 294597,
  "Quantity": 1,
  "RunningNumber": 1,
  "SubscriptionId": "S67645948",
  "UpdateAction": 2,
  "AlignmentSettings": {
    "AlignToCurrentInterval": false,
    "GetCustomerPricePreviewOnly": false
  }
}'
import http.client
import json

conn = http.client.HTTPSConnection("rest.cleverbridge.com")
payload = json.dumps({
  "ProductId": 294597,
  "Quantity": 1,
  "RunningNumber": 1,
  "SubscriptionId": "S67645948",
  "UpdateAction": 2,
  "AlignmentSettings": {
    "AlignToCurrentInterval": False,
    "GetCustomerPricePreviewOnly": False
  }
})
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Basic YOUR_BASE64_ENCODED_CREDENTIALS'
}
conn.request("POST", "/subscription/updatesubscriptionitem", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
var https = require('follow-redirects').https;
var fs = require('fs');

var options = {
  'method': 'POST',
  'hostname': 'rest.cleverbridge.com',
  'path': '/subscription/updatesubscriptionitem',
  'headers': {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Authorization': 'Basic YOUR_BASE64_ENCODED_CREDENTIALS'
  },
  'maxRedirects': 20
};

var req = https.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function (chunk) {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });

  res.on("error", function (error) {
    console.error(error);
  });
});

var postData = JSON.stringify({
  "ProductId": 294597,
  "Quantity": 1,
  "RunningNumber": 1,
  "SubscriptionId": "S67645948",
  "UpdateAction": 2,
  "AlignmentSettings": {
    "AlignToCurrentInterval": false,
    "GetCustomerPricePreviewOnly": false
  }
});

req.write(postData);

req.end();
Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.post("https://rest.cleverbridge.com/subscription/updatesubscriptionitem")
  .header("Content-Type", "application/json")
  .header("Accept", "application/json")
  .header("Authorization", "Basic YOUR_BASE64_ENCODED_CREDENTIALS")
  .body("{\n  \"ProductId\": 294597,\n  \"Quantity\": 1,\n  \"RunningNumber\": 1,\n  \"SubscriptionId\": \"S67645948\",\n  \"UpdateAction\": 2,\n  \"AlignmentSettings\": {\n    \"AlignToCurrentInterval\": false,\n    \"GetCustomerPricePreviewOnly\": false\n  }\n}")
  .asString();

Response

{
    "AlignmentCustomerGrossPrice": 0.0,
    "AlignmentCustomerNetPrice": 0.0,
    "AlignmentCustomerVatPrice": 0.0,
    "NextBillingCustomerGrossPrice": 9.99,
    "NextBillingCustomerNetPrice": 8.39,
    "NextBillingCustomerVatPrice": 1.60,
    "NextRenewalCustomerGrossPrice": 9.99,
    "NextRenewalCustomerNetPrice": 8.39,
    "NextRenewalCustomerVatPrice": 1.60,
    "PriceCurrencyId": "USD",
    "ResultMessage": "OK"
}

Diagram


flowchart LR
  classDef mainColor fill:#ffffff,color:#555555,stroke:#96C34B,stroke-width:2px;

  A(["&nbsp;&nbsp;<br/><b>Downgrade request</b><br/>Customer selects to downgrade their plan&nbsp;&nbsp;<br/>&nbsp;"]):::mainColor
    --> B(["&nbsp;&nbsp;<br/><b>Schedule downgrade</b><br/><i>Update Subscription Item</i> schedules change for next billing date&nbsp;&nbsp;<br/>&nbsp;"]):::mainColor
    --> C(["&nbsp;&nbsp;<br/><b>Billing & change</b><br/>Cleverbridge applies downgrade and bills new price&nbsp;&nbsp;<br/>&nbsp;"]):::mainColor