Customize Subscription Renewal Price
Overview
This guide shows you how to implement the Get Subscription and the Update Subscription Item Price API endpoints to customize subscription renewal price.
Use Case
- A Cloudify customer plans to buy more seats in the future and asks for a price reduction.
- Cloudify agrees and reduces the price per seat from $5.00 to $4.85.
- Cloudify updates the subscription seat price using the Update Subscription Item Price API endpoint.
- Cleverbridge automatically renews the subscription and bills the customer.
Implement API endpoints
Before you start
Make sure that:
- The subscription has the status
Active. - Any changes made, including the price and/or quantity, apply to all future billing events unless modified subsequently.
- Use of the
CustomerPriceparameter in the API response is required.
Before doing so, see Understand Customer Price. - Use the
AlignmentSettingsparameter for the subscription in the API response is required.
Before doing so, see Get Started with Subscription API > Alignment Settings.
For more information on which API endpoint to use, see Guidelines for When to Use UpdateSubscriptionItem vs. UpdateSubscriptionItemPrice.
ImportantGet 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: Retrieve the Quantity of Users
To retrieve the current subscription item quantity:
- Call the Get Subscription API endpoint.
- In the
SubscriptionItemarray data returned in the response, locate the single instance in the array for which both of the following statements are true:
RunningNumbermatches the running number of the subscription item for which the quantity is needed.- The
IsCurrentparameter istrue.
- Retrieve the current quantity for the Users subscription item from this instance of the array.
Parameters
| Parameter | Type | Required | Example | Notes |
|---|---|---|---|---|
| RunningNumber | int | Yes | 1 | Running number of the item in the subscription. |
| SubscriptionId | str | Yes | S67531904 | The unique identifier of the subscription. |
| isCurrent | bool | Yes | true | Whether to return only the current state. |
Request
curl --request GET \
--url "https://rest.cleverbridge.com/subscription/getsubscription?RunningNumber=1&SubscriptionId=S67531904&isCurrent=true" \
--header "Accept: application/json" \
--header "Authorization: Basic YOUR_BASE64_ENCODED_CREDENTIALS"import json
from urllib.parse import urlencode
from urllib.request import Request, urlopen
BASE_URL = "https://rest.cleverbridge.com/subscription/getsubscription"
params = {
"RunningNumber": 1,
"SubscriptionId": "S67531904",
"isCurrent": "true"
}
query_string = urlencode(params)
url = f"{BASE_URL}?{query_string}"
req = Request(
url,
method="GET",
headers={
"Accept": "application/json",
"Authorization": "Basic YOUR_BASE64_ENCODED_CREDENTIALS"
}
)
with urlopen(req) as resp:
body = resp.read().decode("utf-8")
print("Status:", resp.status)
print(json.dumps(json.loads(body), indent=2))const https = require("https");
const baseUrl = "https://rest.cleverbridge.com";
const path =
"/subscription/getsubscription?RunningNumber=1&SubscriptionId=S67531904&isCurrent=true";
const options = {
method: "GET",
headers: {
Accept: "application/json",
Authorization: "Basic YOUR_BASE64_ENCODED_CREDENTIALS",
},
};
const req = https.request(baseUrl + path, options, (res) => {
let data = "";
res.on("data", (chunk) => {
data += chunk;
});
res.on("end", () => {
console.log("Status:", res.statusCode);
try {
console.log(JSON.stringify(JSON.parse(data), null, 2));
} catch {
console.log(data);
}
});
});
req.on("error", (err) => {
console.error("Request error:", err);
});
req.end();
import java.io.IOException;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
public class GetSubscriptionSample {
public static void main(String[] args) throws IOException, InterruptedException {
String baseUrl = "https://rest.cleverbridge.com/subscription/getsubscription";
String query =
"RunningNumber=" + URLEncoder.encode("1", StandardCharsets.UTF_8) +
"&SubscriptionId=" + URLEncoder.encode("S67531904", StandardCharsets.UTF_8) +
"&isCurrent=" + URLEncoder.encode("true", StandardCharsets.UTF_8);
String url = baseUrl + "?" + query;
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Accept", "application/json")
.header("Authorization", "Basic YOUR_BASE64_ENCODED_CREDENTIALS")
.GET()
.build();
HttpClient client = HttpClient.newHttpClient();
HttpResponse<String> response =
client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status: " + response.statusCode());
System.out.println(response.body());
}
}Response
From the Items object, retrieve the quantity of the subscription seats. Example: "Quantity": 10
{
"Subscription": {
"CustomerCurrencyId": "USD",
"CustomerId": 157610360,
"CustomerReferenceId": "MbZHngtCou1wRCBahnccYkNqsVdpgc6Fl9hzENQ1",
"CustomerReferenceNo": "",
"EndDate": null,
"GracePeriodDays": 0,
"Id": 67531904,
"IntervalDayCount": 0,
"IntervalMonthCount": 1,
"BillingIntervalDayCount": 0,
"BillingIntervalMonthCount": 0,
"Items": [
{
"Couponcode": "",
"DeactivationDate": null,
"EndDate": null,
"IsCurrent": true,
"LastIntervalNo": 0,
"NextBillingCurrencyId": "USD",
"NextBillingCustomerGrossPrice": 50.0,
"NextBillingCustomerNetPrice": 42.02,
"NextBillingCustomerVatPrice": 7.98,
"NextRenewalCustomerGrossPrice": 50.0,
"NextRenewalCustomerNetPrice": 42.02,
"NextRenewalCustomerVatPrice": 7.98,
"ProductId": 292973,
"ProductName": "Cloudify Seat",
"ProductNameExtension": "",
"PromotionId": null,
"Quantity": 10, //the quantity of the subscription seats.
"RecurrenceCount": null,
"RunningNo": 1,
"StartDate": "2026-02-09T15:43:07.20517",
"Status": 1,
"SubscriptionId": 67531904,
"SubscriptionPurchaseItems": [
{
"PurchaseId": 531157892,
"PurchaseItemRunningNo": 1,
"SubscriptionIntervalNo": 0,
"BillingIntervalNo": 0
}
],
"Version": 1,
"VersionActiveDate": "2026-02-09T15:43:07.20517"
}
],
"LastIntervalNo": 0,
"LastBillingIntervalNo": 0,
"NextBillingCurrencyId": "USD",
"NextBillingCustomerGrossPrice": 50.0,
"NextBillingCustomerNetPrice": 42.02,
"NextBillingCustomerVatPrice": 7.98,
"NextRenewalCustomerGrossPrice": 50.0,
"NextRenewalCustomerNetPrice": 42.02,
"NextRenewalCustomerVatPrice": 7.98,
"NextBillingDate": "2026-03-09T15:43:07.20517",
"NextRenewalDate": "2026-03-09T15:43:07.20517",
"NextBillingDateReminder": "2026-03-07T15:43:07.20517Z",
"PaymentInfo": {
"CardExpirationDate": {
"Month": 12,
"Year": 2027
},
"CardLastFourDigits": "765T",
"Currency": null,
"CurrencyId": null,
"IsPurchaseOrder": null,
"PaymentType": "Visa",
"PaymentTypeId": "CCA_VIS"
},
"RenewalType": "Automatic",
"StartDate": "2026-02-09T15:43:07.20517",
"StartIntervalDayCount": 0,
"StartIntervalMonthCount": 1,
"Subscriptionstatus": 1,
"ManagementModel": "One",
"SelfServiceUrl": "https://www.cleverbridge.com/864/s/s67531904-VlWdITPJkw6s6kFr"
},
"ResultMessage": "OK"
}Step 2: Update Subscription Item Price
Set the parameters in the Update Subscription Item Price API call to the values listed in the table.
Parameter | Type | Required | Example | Notes |
|---|---|---|---|---|
AlignmentSettings | obj | No | AlignToCurrentInterval: false GetCustomerPricePreviewOnly: false | The subscription is changed as requested in the API call. |
CustomerPrice | obj | Yes |
| Set new price at $4.00 |
Quantity | int | Yes | 20 | Number of seats in the subscription. |
RunningNumber | int | Yes | 1 | Running number of the item in the subscription. |
SubscriptionId | str | Yes | S67531904 | The unique identifier of the subscription. |
UpdateAction | str | No | upgrade | The value set does not affect transaction processing. |
NoteThe
UpdateActionparameter 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)
JSON body
{
"SubscriptionId": "S67531904",
"RunningNumber": 1,
"UpdateAction": "upgrade",
"ForcePriceRecalculation": false,
"Quantity": 20,
"CustomerPrice": {
"CurrencyId": "USD",
"IsGross": true,
"Value": 4.0
},
"AlignmentSettings": {
"AlignToCurrentInterval": false,
"GetCustomerPricePreviewOnly": false,
"GetCustomerPricePreviewOnly": false
}
}Request
curl --location 'https://rest.cleverbridge.com/subscription/updatesubscriptionitemprice'
--header 'Content-Type: application/json'
--header 'Accept: application/json'
--header 'Authorization: Basic YOUR_BASE64_ENCODED_CREDENTIALS'
--data '{
"SubscriptionId": "S67531904",
"RunningNumber": 1,
"UpdateAction": "upgrade",
"ForcePriceRecalculation": false,
"Quantity": 20,
"CustomerPrice": {
"CurrencyId": "USD",
"IsGross": true,
"Value": 4.0
},
"AlignmentSettings": {
"AlignToCurrentInterval": false,
"GetCustomerPricePreviewOnly": false,
"GetCustomerPricePreviewOnly": false
}
}'import http.client
import json
conn = http.client.HTTPSConnection("rest.cleverbridge.com")
payload = json.dumps({
"SubscriptionId": "S67531904",
"RunningNumber": 1,
"UpdateAction": "upgrade",
"Quantity": 20,
"ForcePriceRecalculation": False,
"CustomerPrice": {
"CurrencyId": "USD",
"IsGross": True,
"Value": 4.00
},
"AlignmentSettings": {
"AlignToCurrentInterval": False,
"GetCustomerPricePreviewOnly": False
}
})
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Basic YOUR_BASE64_ENCODED_CREDENTIALS'
}
conn.request("POST", "/subscription/updatesubscriptionitemprice", 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/updatesubscriptionitemprice',
'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({
"SubscriptionId": "S67531904",
"RunningNumber": 1,
"UpdateAction": "upgrade",
"ForcePriceRecalculation": false,
"Quantity": 20,
"CustomerPrice": {
"CurrencyId": "USD",
"IsGross": true,
"Value": 4.00
},
"AlignmentSettings": {
"AlignToCurrentInterval": false,
"GetCustomerPricePreviewOnly": false
}
});
req.write(postData);
req.end();Unirest.setTimeouts(0, 0);
HttpResponse<String> response = Unirest.post("https://rest.cleverbridge.com/subscription/updatesubscriptionitemprice")
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.header("Authorization", "Basic YW5uYS5rdWxjenlja2E6QExvZWJhdWVyMjAyNg==")
.body("{\n \"SubscriptionId\": \"S67531904\",\n \"RunningNumber\": 1,\n \"UpdateAction\": \"upgrade\",\n \"ForcePriceRecalculation\": false,\n \"Quantity\": 20,\n \"CustomerPrice\": {\n \"CurrencyId\": \"USD\",\n \"IsGross\": true,\n \"Value\": 4.0\n },\n \"AlignmentSettings\": {\n \"AlignToCurrentInterval\": false,\n \"GetCustomerPricePreviewOnly\": false,\n \"GetCustomerPricePreviewOnly\": false\n }\n}")
.asString();Diagram
flowchart LR
classDef mainColor fill:#ffffff,color:#96C34B,stroke:#96C34B,stroke-width:2px;
A([" <br/>A Cloudify customer wants to buy more seats<br/>and asks for a discount <br/> "]):::mainColor
--> B([" <br/>Cloudify reduces the price per seat<br/>from $5.00 to $4.85 <br/> "]):::mainColor
--> C([" <br/>Cleverbridge automatically renews the subscription<br/>and bills the customer <br/> "]):::mainColor
Updated 20 days ago