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.

ConfigurationYear 1Year 2Year 3
Default (first year enabled)123
First year disabled012

The API exposes both a counter and a boolean:

  • available_exchanges — number of exchanges remaining in the current quota period
  • available_actions.change_itemtrue when 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_on date is recalculated for the new period
  • The exchange quota resets for the new year

Checking Availability

GET /api/public/v1/subscriptions/:id

The subscription response includes:

available_actions.change_item

true when an exchange is currently available — quota not exceeded, subscription active and paid, cart confirmed.

available_actions.extend_period

true 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

The 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_itemextend_periodMeaning
truefalseExchange available, standard exchange (no extension needed)
truetrueExchange available, subscription in last year — exchange must include extension
falsetrueQuota used up for this year, subscription in last year — no exchange possible until next year
falsefalseNo exchange available

Triggering an Exchange

Use the Update Products endpoint:

POST /api/public/v1/subscriptions/:id/update_products

Pass the desired final state of items. The API automatically determines what was added, removed, or exchanged.

Relevant parameters:

ParameterTypeDefaultDescription
apply_yearly_limitbooleanfalseIf true, the request fails with 422 when the yearly exchange quota is exceeded
extend_durationbooleanfalseIf 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
}