[API Guide] Extend Billing Interval of the Original Seat

Overview

This guide shows you how to implement the Update Subscription Item API endpoint twice to co-term subscription items by extending the billing interval of the original seat.

Use case

  1. A customer purchased a Cloudify Storage subscription with 1 seat on April 30, 2026. The subscription renews on a monthly billing cycle at $100.00 per month, with the next scheduled renewal date set to May 30, 2026.

  2. Cloudify presents the customer with a promotional offer: purchase 1 additional seat for $80.00 per month provided the customer immediately extends the subscription term for the next 6 months.

  3. On the Customer Self-Service page, the application calls the Update Subscription Item API endpoint in preview mode to calculate and display:

  4. The customer confirms this purchase and clicks a Buy Now button.

  5. The Update Subscription Item API endpoint is called again to extend the billing interval of the original seat and add the second seat.


Result

The customer now has 2 active seats, and the subscription renewal date for both seats is updated to November 30, 2026.

Implement the API endpoints

Call the Update Subscription Item API endpoint twice, in the first step to create a preview of the price breakdown, in the second call to extend the billing interval of the original seat and add the second seat.

Before you start

Make sure that:

  • The subscription has the status Active.
  • Using the Update Subscription ItemSet to false if you want to suppress the automatically generated email that informs the customer about the subscription update. API endpoint to change the billing interval of a subscription is only supported for single-item subscriptions (which is the most common type of subscription).
  • When replacing one subscription item with another, the original and the replacement items must have the same currency and billing interval.
  • The price update takes place on the next renewal date.
  • Any changes made, including the price and/or quantity, apply to current and all future billing events unless modified subsequently.

  • If you add a subscription item, a history of revisions is created automatically. It is important to confirm that the current version receives the update.

For more information on which API endpoint to use, see Guidelines for When to Use UpdateSubscriptionItem vs. UpdateSubscriptionItemPrice.

🚧

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.

Check how to Add volume pricing in the Cleverbridge platform.

Step 1: Preview of price and next billing date (first call)

If the API call is formatted as described below, it will:

  • Calculate price if the new purchase and renewal are made
  • Return the next billing date in the NextBillingDate parameter of the API response (so that it can be provided to the customer)
  • Not change any data in the Cleverbridge system

Parameters

Parameter

Type

Required

Example

Notes

AlignmentSettings

obj

Yes

AlignToCurrentInterval: true GetCustomerPricePreviewOnly: true

The subscription is changed as requested in the API call.

ProductId

int

Yes

293103

Product ID for the subscription item usage.

RunningNumber

int

Yes

1

Running number of the item in the subscription.

Quantity

int

Yes

2

Total number of items after the update.

SubscriptionId

str

Yes

S68663881

The unique identifier of the subscription.

UpdateAction

str

No

0

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

JSON body

{
    "ProductId": 293103,
    "RunningNumber": 1,
    "Quantity": 2,
    "SubscriptionId": "S68663881",
    "UpdateAction": 0,
    "AlignmentSettings": {
        "AlignToCurrentInterval": true,
        "GetCustomerPricePreviewOnly": true
    }
}

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": 293103,
    "RunningNumber": 1,
    "Quantity": 2,
    "SubscriptionId": "S68663881",
    "UpdateAction": 0,
    "AlignmentSettings": {
        "AlignToCurrentInterval": true,
        "GetCustomerPricePreviewOnly": true
    }
}'
import http.client
import json

conn = http.client.HTTPSConnection("rest.cleverbridge.com")
payload = json.dumps({
  "ProductId": 293103,
  "RunningNumber": 1,
  "Quantity": 2,
  "SubscriptionId": "S68663881",
  "UpdateAction": 0,
  "AlignmentSettings": {
    "AlignToCurrentInterval": True,
    "GetCustomerPricePreviewOnly": True
  }
})
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 request = require('request');
var options = {
  'method': 'POST',
  'url': 'https://rest.cleverbridge.com/subscription/updatesubscriptionitem',
  'headers': {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Authorization': 'Basic YOUR_BASE64_ENCODED_CREDENTIALS'
  },
  body: JSON.stringify({
    "ProductId": 293103,
    "RunningNumber": 1,
    "Quantity": 2,
    "SubscriptionId": "S68663881",
    "UpdateAction": 0,
    "AlignmentSettings": {
      "AlignToCurrentInterval": true,
      "GetCustomerPricePreviewOnly": true
    }
  })

};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
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\": 293103,\n    \"RunningNumber\": 1,\n    \"Quantity\": 2,\n    \"SubscriptionId\": \"S68663881\",\n    \"UpdateAction\": 0,\n    \"AlignmentSettings\": {\n        \"AlignToCurrentInterval\": true,\n        \"GetCustomerPricePreviewOnly\": true\n    }\n}")
  .asString();

Response

{
    "AlignmentCustomerGrossPrice": 76.67,
    "AlignmentCustomerNetPrice": 64.43,
    "AlignmentCustomerVatPrice": 12.24,
    "NextBillingCustomerGrossPrice": 200.0,
    "NextBillingCustomerNetPrice": 168.07,
    "NextBillingCustomerVatPrice": 31.93,
    "NextRenewalCustomerGrossPrice": 200.0,
    "NextRenewalCustomerNetPrice": 168.07,
    "NextRenewalCustomerVatPrice": 31.93,
    "PriceCurrencyId": "USD",
    "ResultMessage": "OK"
}

Step 2: Add additional seat immediately at a discounted price

In the second call, update the customer's subscription data in the Cleverbridge platform:

Parameters

Parameter

Type

Required

Example

Notes

AlignmentSettings

obj

No

AlignToCurrentInterval: true

GetCustomerPricePreviewOnly: false

The subscription is changed as requested in the API call.

ProductId

int

Yes

292973

Product ID for the subscription item usage.

RunningNumber

int

Yes

1

Running number of the item in the subscription.

Quantity

int

Yes

2

Total number of items after the update.

SubscriptionId

str

Yes

The unique identifier of the subscription.

UpdateAction

str

No

upgrade

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

Response

Diagram

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

  A(["&nbsp;&nbsp;<br/><b>Promotional offer sent</b><br/>The customer receives an offer to buy additional seat <br/> at a discounted price&nbsp;&nbsp;<br/>&nbsp;"]):::mainColor
    --> B(["&nbsp;&nbsp;<br/><b>Customer Self-Service</b><br/><i>Update Subscription Item</i> endpoint to obtain and display the price of the additional seat&nbsp;&nbsp;<br/>&nbsp;"]):::mainColor
    --> C(["&nbsp;&nbsp;<br/><b>Purchase confirmation</b><br/>The customer clicks <b>Buy now</b>. <br/><i>Update Subscription Item</i> endpoint  used to extend the subscription&nbsp;&nbsp;<br/>&nbsp;"]):::mainColor