[API Guide] Align Subscription

Overview

This guide shows you how to implement the Align Subscriptions API endpoint to align multiple subscriptions to the same billing date.

Use case

  1. A customer wants to align two monthly subscriptions so they are billed on the same date.
  2. The customer currently has the following subscriptions:
SubscriptionNext Billing DateNext PaymentSubscriptionId
Primary: Cloudify Storage Monthly Renewal27.05.2026$100.00S68618572
Secondary: Cloudify M23.05.2026$2,000.00S68574751

Because Cloudify M has the later billing date, it is used as the primary subscription (S68618572). The subscription with the earlier billing date, Cloudify Storage Monthly Renewal (S68574751), is used as the secondary subscription.

Result

The primary and secondary subscriptions are combined into a single subscription with two subscription items that share the same billing date. The secondary subscription now has the status Finished, and the subscription item has the status Removed.


Implement the API endpoints

Before you start

Make sure that:

  • Both subscriptions have the status Active
  • Both subscriptions use the same billing interval (for example, monthly)
  • Both subscriptions use the same currency
  • The calculated billing amount is positive
🚧

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.


📘

Note

Aligning the secondary subscription to a later billing date may reduce revenue for the adjusted billing interval because the unused portion of the current billing interval may not be charged when the billing dates are aligned.

Step 1: Preview subscription alignment

Parameters

Parameter

Type

Required

Example

Notes

AlignmentSettings

obj

Yes

AlignToCurrentInterval: true

GetCustomerPricePreviewOnly: true

The subscription is not changed. The endpoint only returns a pricing preview.

PrimarySubscriptionId

str

Yes

S68618572

The unique identifier of the primary subscription.

SecondarySubscriptionId

str

Yes

S68574751

The unique identifier of the secondary subscription.


Request

curl --location 'https://rest.cleverbridge.com/subscription/alignsubscriptions' 
--header 'Content-Type: application/json' 
--header 'Accept: application/json' 
--header 'Authorization: Basic YOUR_BASE64_ENCODED_CREDENTIALS' 
--data '{
  "PrimarySubscriptionId": "S68618572",
  "SecondarySubscriptionId": "S68574751",
  "AlignmentSettings": {
    "AlignToCurrentInterval": true,
    "GetCustomerPricePreviewOnly": true
  }
}'
import http.client
import json

conn = http.client.HTTPSConnection("rest.cleverbridge.com")
payload = json.dumps({
  "PrimarySubscriptionId": "S68618572",
  "SecondarySubscriptionId": "S68574751",
  "AlignmentSettings": {
    "AlignToCurrentInterval": True,
    "GetCustomerPricePreviewOnly": True
  }
})
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Basic YOUR_BASE64_ENCODED_CREDENTIALS'
}
conn.request("POST", "/subscription/alignsubscriptions", 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/alignsubscriptions',
  'headers': {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Authorization': 'Basic YOUR_BASE64_ENCODED_CREDENTIALS'
  },
  body: JSON.stringify({
    "PrimarySubscriptionId": "S68618572",
    "SecondarySubscriptionId": "S68574751",
    "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/alignsubscriptions")
  .header("Content-Type", "application/json")
  .header("Accept", "application/json")
  .header("Authorization", "Basic YOUR_BASE64_ENCODED_CREDENTIALS")
  .body("{\n  \"PrimarySubscriptionId\": \"S68618572\",\n  \"SecondarySubscriptionId\": \"S68574751\",\n  \"AlignmentSettings\": {\n    \"AlignToCurrentInterval\": true,\n    \"GetCustomerPricePreviewOnly\": true\n  }\n}")
  .asString();

Response

{
    "AlignmentCustomerGrossPrice": 200.0,
    "AlignmentCustomerNetPrice": 168.07,
    "AlignmentCustomerVatPrice": 31.93,
    "NextBillingCustomerGrossPrice": 2100.0,
    "NextBillingCustomerNetPrice": 1764.70,
    "NextBillingCustomerVatPrice": 335.30,
    "NextRenewalCustomerGrossPrice": 2100.0,
    "NextRenewalCustomerNetPrice": 1764.70,
    "NextRenewalCustomerVatPrice": 335.30,
    "PriceCurrencyId": "USD",
    "ResultMessage": "OK"
}

Step 2: Execute subscription alignment

Parameters

Parameter

Type

Required

Example

Notes

AlignmentSettings

obj

Yes

AlignToCurrentInterval: true

GetCustomerPricePreviewOnly: false

The subscription is changed as requested.
Aligns the subscriptions starting with the next billing cycle.

PrimarySubscriptionId

str

Yes

S68618572

The unique identifier of the primary subscription.

SecondarySubscriptionId

str

Yes

S68574751

The unique identifier of the secondary subscription.

Request

curl --location 'https://rest.cleverbridge.com/subscription/alignsubscriptions' 
--header 'Content-Type: application/json' 
--header 'Accept: application/json' 
--header 'Authorization: Basic YOUR_BASE64_ENCODED_CREDENTIALS' 
--data '{
  "PrimarySubscriptionId": "S68618572",
  "SecondarySubscriptionId": "S68574751",
  "AlignmentSettings": {
    "AlignToCurrentInterval": true,
    "GetCustomerPricePreviewOnly": false
  }
}'
import http.client
import json

conn = http.client.HTTPSConnection("rest.cleverbridge.com")
payload = json.dumps({
  "PrimarySubscriptionId": "S68618572",
  "SecondarySubscriptionId": "S68574751",
  "AlignmentSettings": {
    "AlignToCurrentInterval": True,
    "GetCustomerPricePreviewOnly": False
  }
})
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Basic YOUR_BASE64_ENCODED_CREDENTIALS'
}
conn.request("POST", "/subscription/alignsubscriptions", 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/alignsubscriptions',
  'headers': {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Authorization': 'Basic YOUR_BASE64_ENCODED_CREDENTIALS'
  },
  body: JSON.stringify({
    "PrimarySubscriptionId": "S68618572",
    "SecondarySubscriptionId": "S68574751",
    "AlignmentSettings": {
      "AlignToCurrentInterval": true,
      "GetCustomerPricePreviewOnly": false
    }
  })

};
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/alignsubscriptions")
  .header("Content-Type", "application/json")
  .header("Accept", "application/json")
  .header("Authorization", "Basic YOUR_BASE64_ENCODED_CREDENTIALS")
  .body("{\n  \"PrimarySubscriptionId\": \"S68618572\",\n  \"SecondarySubscriptionId\": \"S68574751\",\n  \"AlignmentSettings\": {\n    \"AlignToCurrentInterval\": true,\n    \"GetCustomerPricePreviewOnly\": false\n  }\n}")
  .asString();

Response

{
    "AlignmentCustomerGrossPrice": 200.0,
    "AlignmentCustomerNetPrice": 168.07,
    "AlignmentCustomerVatPrice": 31.93,
    "NextBillingCustomerGrossPrice": 2100.0,
    "NextBillingCustomerNetPrice": 1764.70,
    "NextBillingCustomerVatPrice": 335.30,
    "NextRenewalCustomerGrossPrice": 2100.0,
    "NextRenewalCustomerNetPrice": 1764.70,
    "NextRenewalCustomerVatPrice": 335.30,
    "PriceCurrencyId": "USD",
    "ResultMessage": "OK"
}

Diagram


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

  A(["&nbsp;&nbsp;<br/><b>Two monthly subscriptions</b><br/>A customer would like to align two monthly subscriptions&nbsp;&nbsp;<br/>&nbsp;"]):::mainColor
    --> B(["&nbsp;&nbsp;<br/><b>Align Subscriptions</b><br/>The <i> Align Subscriptions </i>API endpoint is used to consolidate the date&nbsp;&nbsp;<br/>&nbsp;"]):::mainColor
    --> C(["&nbsp;&nbsp;<br/><b>Billing</b><br/>Both subscriptions are aligned to the same billing date&nbsp;&nbsp;<br/>&nbsp;"]):::mainColor