Skip to main content
POST
/
v1
/
subscriptions
/
calculate-buyout
Calculate buyout price
curl --request POST \
  --url https://api-eu.flexportal.io/v1/subscriptions/calculate-buyout \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --header 'Tenant-ID: <tenant-id>' \
  --data '
{
  "rentalId": "<string>"
}
'
{
  "success": true,
  "buyoutPrice": 123,
  "remainingPayments": 123,
  "depreciatedValue": 123
}

Overview

Calculate the buyout price for a subscription before processing the actual buyout. This endpoint returns a recommended price based on remaining contract value and configured residual rates—use it to present buyout options to customers.
This is a read-only calculation—it doesn’t modify the subscription. Call Buyout Subscription to actually process the buyout.

Request Fields

FieldRequiredDescription
subscriptionIdYesThe subscription to calculate for

Example Request

{
  "subscriptionId": "sub_abc123"
}

Response Structure

{
  "success": true,
  "subscriptionId": "sub_abc123",
  "calculation": {
    "buyoutPrice": 658.00,
    "breakdown": {
      "remainingContractValue": 516.00,
      "residualValue": 142.00,
      "monthsRemaining": 4,
      "monthlyAmount": 129.00
    },
    "costRecovery": {
      "acquisitionCost": 1800.00,
      "totalCollected": 1548.00,
      "projectedAfterBuyout": 2206.00,
      "projectedMargin": 406.00,
      "marginPercent": 22.6
    }
  }
}

Understanding the Calculation

Remaining Contract Value

The value of remaining payments:
remainingContractValue = monthsRemaining × monthlyAmount

Residual Value

The minimum asset value at contract end, typically:
  • A percentage of acquisition cost (e.g., 5-15%)
  • Or a fixed minimum amount
  • Configured in tenant settings

Buyout Price

buyoutPrice = remainingContractValue + residualValue

Common Use Cases

1. Quoting Customers

async function getBuyoutQuote(subscriptionId) {
  const calc = await calculateBuyout({ subscriptionId });

  return {
    price: calc.calculation.buyoutPrice,
    monthsLeft: calc.calculation.breakdown.monthsRemaining,
    savedMonths: calc.calculation.breakdown.monthsRemaining,
    message: `Buy now for €${calc.calculation.buyoutPrice} (saves ${calc.calculation.breakdown.monthsRemaining} months of payments)`
  };
}

2. Evaluating Profitability

async function shouldOfferBuyout(subscriptionId) {
  const calc = await calculateBuyout({ subscriptionId });

  const marginPercent = calc.calculation.costRecovery.marginPercent;

  return {
    recommend: marginPercent > 15, // Only offer if > 15% margin
    margin: marginPercent,
    buyoutPrice: calc.calculation.buyoutPrice
  };
}

3. Bulk Analysis

async function analyzeBuyoutOpportunities() {
  // Get subscriptions ending in next 3 months
  const { subscriptions } = await listSubscriptions({
    status: 'active',
    endDateTo: threeMonthsFromNow
  });

  const opportunities = [];

  for (const sub of subscriptions) {
    const calc = await calculateBuyout({ subscriptionId: sub.subscriptionId });

    if (calc.calculation.costRecovery.marginPercent > 20) {
      opportunities.push({
        subscriptionId: sub.subscriptionId,
        customer: sub.customerId,
        product: sub.productName,
        buyoutPrice: calc.calculation.buyoutPrice,
        margin: calc.calculation.costRecovery.marginPercent
      });
    }
  }

  return opportunities;
}

Presentation Tips

When showing buyout prices to customers:
  • Highlight savings: Show total remaining payments vs buyout price
  • Ownership benefits: Emphasize they keep the device forever
  • No more payments: Monthly billing stops after buyout
  • Immediate: They can own it today

Authorizations

Authorization
string
header
required

API key obtained from FlexPortal dashboard

Headers

Tenant-ID
string
required

Your tenant identifier

Body

application/json
rentalId
string
required

The subscription ID

Response

Buyout calculation

success
enum<boolean>
required
Available options:
true,
false
buyoutPrice
number
required
remainingPayments
number
required
depreciatedValue
number
required