Update a subscription

You can upgrade or downgrade an active subscription by changing the product associated with it. However, free trials associated with the new product are ignored. To apply a free trial period to an upgraded or downgraded subscription, apply the change from the Activity page.

Subscription Update Flags

The following flags modify behavior when used in conjunction with product paths as part of a subscription change request.

Prorate

Editing a subscription with prorate flag set to true will first calculate the remaining balance on the subscription before the changes are applied, then apply the changes and either deduct the balance from the applicable remainder charges (for upgrades) or refund/credit the buyer for the excess charges (for downgrades).
A proration order is created for the changes made accessible under the subscription detail page on the FastSpring app

Preview

The preview flag in combination with prorate flag returns a response of proratable charges and credits for a recent and eligible plan change.

ProratePreviewBehavior
truefalseThe POST to subscriptions endpoint calculates the charges and credits resulting from the subscription changes, prorate the changes, and commits the changes accordingly. It returns a response based on the success/failure of the subscription change update.
truetrueThe POST to subscriptions endpoint should calculate the charges and credits resulting from the subscription changes, prorate the changes and return the estimates as a response. It will NOT commit the changes.
falsetrueNot Supported
falsefalseThe POST to subscriptions endpoint modifies the subscription as requested. It does NOT prorate the proposed changes. It also does NOT return a response containing a preview of the changes. It will return a response based on the success/failure of the subscription change update.

Modify the primary subscription product path, quantity, next charge date, or coupon

An upgrade is when your monthly recurring revenue increases after the change, otherwise the change is marked as a downgrade. The POST method allows modification of not just the primary product, but also other details on the subscription like dates, coupons, or quantity.

{
    "subscriptions": [
    {
        "subscription": "subscription-uuid-1",     // Subscription ID to be updated (From Subscription detail page)
        "product": "new-monthly-subscription",     // Catalog product path of the new subscription primary product from the catalog 
        "quantity": 1,                             // quantity of the new product
        "coupons": ["coupon_code"],                // only supports one coupon to be applied, pass an empty array to remove coupon
        "prorate" : true                           // If true the subscription is prorated upto the day of API call - any refunds are applied as credit to the remaining period
    }
  ]
}
{
  "subscriptions": [
    {
      "subscription": "subscription-uuid-2",
      "next": 1712188800000, // or "yyyy-mm-dd",        // Next charge date (UTC epoch time in millis) - Setting next date in past returns an error
      "end": "2024-12-01",  // or UTC Millis or 0,      // Last charge date will be on or before this date. 0 as unlimited (indefinitely renews) subscription
      "product": "subscription-product-1",
      "quantity": 1,
      "coupons": ["valid_coupon_code"],     // Only supports one coupon to be applie. Pass an empty array to remove coupon.
      "prorate": false                      // When implementing proration. Cannot prorate with updating next charge date.
    }, ...
  ]
}

Error handling: setting next date in the past

When you modify the next charge date, it must be in the future. If you try to update the subscription immediately by setting a time in the past, FastSpring will return an error:

{
  "subscriptions": [
    {
      "subscription": "subscription-uuid-2",
      "next": 1448496000000, // This equals November 26, 2015 (UTC) and generates an error.
      "end": "2024-12-01",  
      "product": "subscription-product-1",
      "quantity": 1,
      "coupons": ["valid_coupon_code"],
      "prorate": false
    }
  ]
}
{
  "action": "subscription.update",
  "subscription": "subscription-uuid-2",
  "result": "error",
  "error": {
    "next": "Please choose a next period date after the current date."
  }
}

// To avoid this error, verify that the next charge date is in the future.

Modify the price or discount for an active subscription without changing the product, programmatically apply a discount without changing the product

{
     "subscriptions":  [
        {
           "subscription":"subscription-id-1",
           "pricing":{
              "price": {"USD":10}
           }
        }
     ]
 }
{
     "subscriptions":  [
        {
           "subscription":"subscription-uuid-4",
           "pricing":{
              "price":{"USD":10},          // see note below about currency
              "discount":{
                 "type":"amount",
                 "amount":3.5,             // (OR can be "amount" : {"USD":3.50}, )  see note below about currency
                 "duration":"all"          // indefinitely apply discount
              }
           }
        }
     ]
 }
// Note:  If the currency is not specified, the currency of the subscription instance will be used;
// if the currency is specified and differs from the subscription's currency, the amount will be converted to subscription's currency.
{
     "subscriptions":  [
        {
           "subscription":"subscription-uuid-3",
           "pricing":{
              "price": 9.95,                // see note below about currency
              "discount":{
                 "type":"percent",
                 "percentage":5,            // (OR can be "amount" : {"USD":3.50}, )  see note below about currency
                 "duration":2               // (OR "all") - restrict discount to periods specified in duration (2 periods for monthly will give 5% discount for 2 monthly rebills)
              }
           }
        }
     ]
 }
// Note:  If the currency is not specified, the currency of the subscription instance will be used; if the currency is specified and differs to the subscription's currency, the amount will be converted to subscription's currency.

Resume a canceled subscription

By default, FastSpring deactivates canceled subscriptions on the next rebill date. Until that date, you can resume a subscription. Customers will be rebilled as if you never canceled it.

To resume a canceled subscription, the body of your request must include the deactivation parameter with a value of null, like in the following example:

{ 
   "subscriptions":[ 
      { 
         "subscription":"OapmwBYlS8CE36nlo7Vm9w",
         "deactivation":null
      }
   ]
}
{
    "subscriptions": [
        {
            "action": "subscription.update",
            "result": "success",
            "subscription": "OapmwBYlS8CE36nlo7Vm9w"
        }
    ]
}

Error handling

If validation fails, you could get one of these responses:

 {
            "action": "subscription.update",
            "subscription": "OapmwBYlS8CE36nlo7Vm9w",
            "result": "error",
            "error": {
              "uncancel": "Subscription is not active."
            }
    },

// You'll get this error if you try to uncancel a subscription that's already been deactivated.
{
        "action": "subscription.update",
        "result": "success",
        "subscription": "OapmwBYlS8CE36nlo7Vm9w"       
    }
    ]
}

// You'll get this response if you try to uncancel a subscription that's not been canceled.

Omitting the deactivation parameter

If you omit "deactivation":nullfrom your request, FastSpring will return a success response, even though the subscription is still canceled:

{  
   "subscriptions":[  
      {  
         "subscription": "OapmwBYlS8CE36nlo7Vm9w"
      }
   ]
}

// This request omits "deactivation":null.
{
    "subscriptions": [
        {
            "action": "subscription.update",
            "result": "success",
            "subscription": "OapmwBYlS8CE36nlo7Vm9w"
        }
    ]
}

// The response returns "result": "success", but the subscription is still canceled.
// Try again with "deactivation":null included in the request body.

Add or edit subscription addon to an active subscription

A Subscription Add-on product path is a standalone non-subscription product path from the catalog - which has been marked in the subscription product as an Add-on Related Offer. Addons renew along with the subscription so the price on the Addon is assumed periodic and not one-time charge.

{
  "subscriptions": [
    {
      "subscription": "subscription-uuid-1",
      "addons": [
        {
          "product": "add-on-seats-being-added-or-updated",  // Catalog product path must be in catalog AND marked as relationship to base/parent subscription product
          "quantity": 20,                                    // update quantity of addon (this can be used for variable component price or usage based pricing like seats, Gigabytes, users, API calls)
          "pricing":{         
             "price": {"USD":5}                              // Addon's pricing (Skip if applying catalog price)                                                             // Can also add discount block but coupons only appliicable at subscription level
          }
        }
      ],
      "prorate": true 												               // Will prorate the subscription thus far, and apply any credits to the difference being charged (or if downgrading, the credits are refunded as a partial order return)
    }
  ]
}
{
  "subscriptions": [
    {
      "subscription": "subscription-id",
      "addons": [
        {
          "product": "existing-add-on-product-being-removed", // addon must be on the subscription
          "quantity": 0
        }
      ],
      "prorate" : false      // No proration (will only apply change in pricing from next period rebill)
    }
  ]
}

Proration Preview

You can request a preview of prorated charges for a subscription that is eligible for proration. For a list of conditions when proration is not applicable, see Managing Active Subscriptions

To request a preview for a prorated subscription, use the example request shown below for an eligible subscription id.

{
    "subscriptions": [ 
      {
        "subscription": "subscription-id",     // Subscription ID to be updated (From Subscription detail page)
        "prorate" : true,                      // If true the subscription is prorated upto the day of API call - any refunds are applied as credit to the remaining period
        "preview" : true
      }
  ]
}

Responses

See the following code snippets for examples of successful responses in case of a charge, or in case of a refund/credit

{
    "subscriptions": [
        {
            "action": "subscription.update",
            "result": "success",
            "subscription": "tbELUuXiSN-kDUcBIW6zIw",
            "prorated": true,
            "proration": {
                "productPath": "add-on-subscription",
                "currency": "USD",
                "nextPeriodStartDate": "2022-11-01T00:00:00.000Z",
                "nextPeriodEndDate": "2022-11-30T00:00:00.000Z",
                "previousRemainingDays": 29.0,
                "periodPastDays": 1.0,
                "nextRemainingDays": 29.0,
                "regularPeriod": {
                    "unit": "MONTH",
                    "unitCount": 1
                },
                "nextPricePerPeriod": {
                    "amount": 410.0,
                    "period": {
                        "count": 1,
                        "unit": "month"
                    }
                },
                "previousPricePerPeriod": {
                    "amount": 205.0,
                    "period": {
                        "count": 1,
                        "unit": "month"
                    }
                },
                "utilizedAmount": 6.83,
                "creditAmount": 198.17,
                "proratedAmount": 396.34,
                "chargeAmount": 198.17
            }
        }
    ]
}
{
    "subscriptions": [
        {
            "action": "subscription.update",
            "result": "success",
            "subscription": "athBG1DPTFuOcw0iwPwi4A",
            "prorated": true,
            "proration": {
                "productPath": "japan-sub",
                "currency": "USD",
                "nextPeriodStartDate": "2022-11-03T00:00:00.000Z",
                "nextPeriodEndDate": "2022-11-09T00:00:00.000Z",
                "previousRemainingDays": 30.0,
                "periodPastDays": 0.0,
                "nextRemainingDays": 7.0,
                "regularPeriod": {
                    "unit": "WEEK",
                    "unitCount": 1
                },
                "nextPricePerPeriod": {
                    "amount": 10.0,
                    "period": {
                        "count": 1,
                        "unit": "week"
                    }
                },
                "previousPricePerPeriod": {
                    "amount": 100.0,
                    "period": {
                        "count": 1,
                        "unit": "month"
                    }
                },
                "utilizedAmount": 0.0,
                "prorateAdjustment": 100.0,
                "proratedAmount": 10.0,
                "refundAmount": 90.0
            }
        }
    ]
}

Response Parameters

Parameter NameDescription
proratedAdjustmentPertains to the old subscription item replaced or removed as part of a recent plan change
This is the prorated price for the unused portion of the item
proratedAmountPertains to the new subscription item added as part of a recent plan change
Prorated price of the new item
refundAmountAmount credited to the customer for the unused portion of the changed item by issuing a refund
utilizedAmountPertains to the old subscription item replaced or removed as part of the recent plan change
This is the prorated amount for the used portion of the item

Error Responses

{
    "subscriptions": [
        {
            "action": "subscription.update",
            "result": "error",
            "subscription": "athBG1DPTFuOcw0iwPwi4A",
            "prorated": false,
            "proration": "Not currently supported"
        }
    ]
}
{
    "subscriptions": [
        {
            "action": "subscription.update",
            "subscription": "ZxMOne-aQ9qY3ykoamuJ-A",
            "result": "error",
            "error": {
                "subscription.prorate": "Items not eligible for proration"
            }
        }
    ]
}
{
    "subscriptions": [
        {
            "action": "subscription.update",
            "subscription": "ZxMOne-aQ9qY3ykoamuJ-A",
            "result": "error",
            "error": {
                "subscription.prorate": "Unable to prorate"
            }
        }
    ]
}

Changing a subscription from automatic renewal to manual renewal

Use the Subscription POST endpoint to switch auto renewed subscriptions to manual renew - where there are no payment details stored on file and requires the buyer to pay for each period manually.

{
    "subscriptions": [
    {
        "subscription": "subscription-uuid-x",
        "manualRenew": "true"
    }
  ]
}

Set an end date and number of remaining periods for a subscription

You can use the /subscriptions endpoint to programmatically adjust a subscription's end date or set a number of remaining periods, ensuring that the subscription doesn't renew beyond a point you determine.

To set an end date and the number of remaining periods, include the following parameters in your POST request payload:


ParameterTypeRequiredDescription
subscriptionstringYesThe unique identifier of the subscription you want to update.
endstringNoThe subscription end date in YYYY-MM-DD format. If you pass a value into this field, it automatically sets isEndDateSet to true.
isEndDateSetbooleanYesIndicates whether the end date is set; must be true if end is also set.
remainingPeriodsintegerNoThe number of remaining periods before the subscription should end. Use as an alternative to specifying an end date. end takes precedence if both end and remainingPeriods are set.
{
  "subscriptions": [
    {
      "subscription": "tbELUuXiSN-kDUcBIW6zIw",     
      "end": "2024-07-19", // Sets the subscription end date to 19 July 2024
      "isEndDateSet": true, 
      "remainingPeriods": 4 // Sets the remaining billing periods to 4                                                          
    }
  ]
}
{
    "subscriptions": [
        {
            "action": "subscription.update",
            "result": "success",
            "subscription": "tbELUuXiSN-kDUcBIW6zIw"
        }
    ]
}

Set a subscription to renew indefinitely

By setting remainingPeriods to null in a POST request to the /subscriptions endpoint, you can reverse any previously set end dates or remaining periods and make the subscription renew indefinitely.

{
  "subscriptions": [
    {
      "subscription": "tbELUuXiSN-kDUcBIW6zIw",     
      "remainingPeriods": null                                                         
    }
  ]
}
{
    "subscriptions": [
        {
            "action": "subscription.update",
            "result": "success",
            "subscription": "tbELUuXiSN-kDUcBIW6zIw"
        }
    ]
}

Add or update a valid tax exemption ID

Add, update, or remove a valid tax exemption ID from an active subscription. Providing the ID will apply appropriate tax exemption rules.

{
    "subscriptions": [
    {
        "subscription": "subscription-uuid-1",     // Subscription ID to be updated (From Subscription detail page)
        "taxExemptId": "tax-exempt-id",     // Update a tax exempt ID 
  ]
}

{
    "subscriptions": [
        {
            "action": "subscription.update",
            "result": "success",
            "subscription": "subscription-uuid-1"
        }
    ]
}
{
    "subscriptions": [
        {
            "action": "subscription.update",
            "subscription": "subscription-uuid-1",
            "result": "error",
            "error": {
                "taxExemptId": "Tax Exempt ID is not valid"
            }
        }
    ]
}

Remove a tax exemption ID from a subscription

To remove a tax exemption ID from a subscription, send a blank string.

{
    "subscriptions": [
        {
            "subscription": "subscription-uuid-1",
            "taxExemptId": ""
        }
    ]
}
{
    "subscriptions": [
        {
            "action": "subscription.update",
            "result": "success",
            "subscription": "subscription-uuid-1"
        }
    ]
}
Language
Credentials
Basic
base64
:
Click Try It! to start a request and see the response here!