Update subscription products
A subscription can handle different type of updates: adding or removing items, and the most common, making an exchange of an item by another one. In any of these case what the API requires is to get the new full cart
Endpoint /api/public/v1/subscriptions/:subscription_id/update_products
Method POST
Swagger https://docs.sequra.com/update/reference/post_api-public-v1-subscriptions-id-update-products#/
Shopper confirmation
An update requires a subscriber confirmation. You have to listen for a webhook to get the confirmation of the operation.
Payload
The service will calculate the difference between items based on their item IDs. In this example, the first item doesn't change, so no more data is required. The second item is new. If the previous cart had another item, that item would be removed because its ID is no longer present.
{
"cart_items": [
{
"id": "5025d4dc-7eb2-4686-9b11-cde4e1469f4d"
},
{
"type": "material_subscription",
"reference": "NEW-001",
"name": "New Product",
"price_with_tax": 30000,
"quantity": 1,
"subscription_price": 1200,
"subscription_period": "24 months"
}
]
}
Response
{
"success": true,
"message": "Productos de suscripción actualizados exitosamente"
}
Exchanges and Extensions
What is an Exchange?
An exchange is when a subscriber replaces one or more items in their active subscription with different items — for example, swapping glasses frames or lenses for a new model.
An exchange is only possible when:
- The subscription is active and paid
- The subscriber has remaining exchange quota (see below)
Exchange Quota
Each subscriber is allowed 1 exchange per year elapsed since activation. The quota is cumulative: after 2 years, up to 2 exchanges have been allowed in total, and so on.
By default, exchanges are allowed from the first year. A per-merchant setting can disable first-year exchanges — in that case the subscriber must wait until year 2 before an exchange is possible.
| Configuration | Year 1 | Year 2 | Year 3 |
|---|---|---|---|
| Default (first year enabled) | 1 | 2 | 3 |
| First year disabled | 0 | 1 | 2 |
The API exposes both a counter and a boolean:
available_exchanges— number of exchanges remaining in the current quota periodavailable_actions.change_item—truewhen an exchange can be performed right now (quota remaining + subscription active and paid + cart confirmed)
What is an Extension?
An extension is not a customer-facing opportunity — it is a condition that applies automatically when a subscription enters its last year.
Once the subscription crosses the extension_available_on date (12 months before the renewal date), any exchange performed by the subscriber must include an extension: the subscription duration is extended by 12 months as part of the exchange. This ensures the subscriber is never exchanging into a subscription that is about to expire.
When an exchange triggers an extension:
- The subscription duration is extended by 12 months
- The
extension_available_ondate is recalculated for the new period - The exchange quota resets for the new year
Checking Availability
GET /api/public/v1/subscriptions/:id
/api/public/v1/subscriptions/:idThe subscription response includes:
available_actions.change_item
available_actions.change_itemtrue when an exchange is currently available — quota not exceeded, subscription active and paid, cart confirmed.
available_actions.extend_period
available_actions.extend_periodtrue when the subscription has entered its last year (current date is past extension_available_on). When this is true, any exchange must be performed with extend_duration: true.
extension_available_on
extension_available_onThe date from which the extension condition applies.
{
"extension_available_on": "2025-12-01",
"available_actions": {
"change_item": true,
"extend_period": true,
...
}
}Interpreting the Combinations
change_item | extend_period | Meaning |
|---|---|---|
true | false | Exchange available, standard exchange (no extension needed) |
true | true | Exchange available, subscription in last year — exchange must include extension |
false | true | Quota used up for this year, subscription in last year — no exchange possible until next year |
false | false | No exchange available |
Triggering an Exchange
Use the Update Products endpoint:
POST /api/public/v1/subscriptions/:id/update_products
/api/public/v1/subscriptions/:id/update_productsPass the desired final state of items. The API automatically determines what was added, removed, or exchanged.
Relevant parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
apply_yearly_limit | boolean | false | If true, the request fails with 422 when the yearly exchange quota is exceeded |
extend_duration | boolean | false | If true, the subscription is extended by 12 months as part of the exchange |
The value of those parameters is responsibility of merchant. It allows to not extend subscription, or to not reduce exchanges quota when fixing some previous
Standard Exchange (no extension)
When change_item is true and extend_period is false:
{
"cart_items": [
{ "id": "existing-item-uuid" },
{
"type": "material_subscription",
"reference": "NEW-FRAME-001",
"name": "New Frame",
"price_with_tax": 25000,
}
],
"apply_yearly_limit": true
}Exchange with Extension
When extend_period is true, pass extend_duration: true. The exchange will extend the subscription by 12 months:
{
"cart_items": [
{ "id": "existing-item-uuid" },
{
"type": "material_subscription",
"reference": "NEW-FRAME-001",
"name": "New Frame",
"price_with_tax": 25000,
}
],
"apply_yearly_limit": true,
"extend_duration": true
}Updated 10 days ago