Proration and Premium Allocation

The Proration plugin controls how premiums, commissions, taxes, and fees are prorated when coverage periods are reduced by either endorsement or cancellation.

In an endorsement, existing peril characteristics are split and premium is prorated to determine the amount to be allocated to the segment before the split timestamp (this is called the “pre-split amount.”) For non-premium bearing endorsements, this also determines the post-split amount (equal to the original amount minus the pre-split amount).

For example, if a characteristics object that covers January 1 2021 to January 1 2022 and has $1000 of allocated premium is endorsed on July 1, approximately half of the premium should be allocated to the January 1 to July 1 segment. You may want to have more nuance:

  • Prorate by months: The premium will be 6 / 12 * 1000, or $500.00

  • Prorate by days: The premium will be 181 / 365 * 1000, $495.89

  • Prorate by milliseconds: The premium (in a daylight savings timezone in the northern hemisphere) will be 15634800000 / 31536000000 * 1000, or $495.78

The proration plugin can handle these and similar scenarios.

Cancellations work similarly but post-split characteristics will not be generated because the coverage is terminated.


The plugin also handles “holdbacks” for retaining extra amounts beyond the proration calculation. This is useful for scenarios like cancellation short rates. See the Proration Holdbacks topic for details.

Plugin Details

Enabling the plugin

To enable the plugin, follow the steps in the plugins topic.

The plugin script

The proration plugin requires a plugin script called prorater.js that exports a function called getProrationResult.

The data object

The data object passed to the plugin looks like this:

segmentSplitTimestamp timestamp
operation string creation | endorsement | renewal | cancellation | reinstatement | withdrawal | action
paymentScheduleName string
tenantTimeZone string

cancellationCategory string
cancellationComments string
cancellationType string
oldPaymentScheduleName string
locator string
policyholderLocator string
productName string
originalContractStartTimestamp timestamp
currency string

Each proration item looks like this:

id string
segmentEndTimestamp timestamp
segmentStartTimestamp timestamp
amount number
followingAmount number
type string premium | tax | commission | fee | technicalPremium | premiumHoldback | taxHoldback | feeHoldback | commissionHoldback | premiumHoldbackReversal | taxHoldbackReversal | feeHoldbackReversal | commissionHoldbackReversal

perilName string
perilCharacteristicsLocator string
fieldValues map<string,[string]>
commissionLocator string
commissionRecipient string
feeLocator string
feeName string
taxLocator string
taxName string


The id property of the proration item is a transient value used to key the plugin input to the response. It is not saved in the database nor is it consistent across calls.


Numeric values sent to the plugin are passed as strings to ensure no loss of precision.

The Plugin Response Object

The plugin requires that the response from the plugin looks like this:


Where each ProrationResponseItem looks like this:

id string
holdbackAmount number
proratedAmount number

holdbackMetadata string


The response from the plugin must conform to the following criteria:

  • The id for each ProrationResponseItem must match that in the corresponding ProrationPluginItem in the input.

  • An output item’s proratedAmount must not exceed the amount of the input item.

  • The holdbackAmount is required. Set its value to 0 if you do not want to create a holdback.

  • You may include holdbackMetadata only if you are also including a positive holdbackAmount in the ProrationResponseItem.

Sample Script (Simple)

This script implements the proration plugin using linear (millisecond-based) proration.

function getProrationResult(data)
  return { items: => prorateItem(data, item)) };
function prorateItem(data, item)
  return {
    proratedAmount: round2(parseFloat(item.amount) * getLinearFraction(data, item)),
    holdbackAmount: 0
function getLinearFraction(data, item)
  return (parseInt(data.segmentSplitTimestamp) - parseInt(item.segmentStartTimestamp))
    / (parseInt(item.segmentEndTimestamp) - parseInt(item.segmentStartTimestamp));
function round2(num)
  return Math.round(num * 100) / 100.0;

exports.getProrationResult = getProrationResult;

Sample Script (Advanced)

This script implements the proration plugin using linear proration for upfront, every_week, and every_two_weeks payment schedules, and monthly proration for other schedules.


This Zip file contains the required library and associated support files for this example.

const { DateCalc } = require('../lib/DateCalc.js');

function getProrationResult(data)
  let dateCalc = new DateCalc(data.tenantTimeZone);
  let fractionFn;
  switch (data.paymentScheduleName)
    case "full-pay":
      fractionFn = getLinearFraction;
    case "every_week":
    case "every_two_weeks":
      fractionFn = getDayFraction;
      fractionFn = getMonthlyFraction;

  return { items: => ({ id:,
                                            proratedAmount: round2(fractionFn(data, item, dateCalc) * item.amount),
                                            holdbackAmount: 0 })) };
function getDayFraction(data, item, dateCalc)
  return dateCalc.dayCountRatio(item.segmentStartTimestamp,
function getMonthlyFraction(data, item, dateCalc)
  return dateCalc.socotraMonthCountRatio(item.segmentStartTimestamp,

function getLinearFraction(data, item, dateCalc)
  return dateCalc.linearRatio(item.segmentStartTimestamp,
function destringifyData(data)
  data.segmentSplitTimestamp = parseInt(data.segmentSplitTimestamp);
  for (const item of data.items)
    item.amount = parseFloat(item.amount);
    item.followingAmount = parseFloat(item.followingAmount);
    item.segmentStartTimestamp = parseInt(item.segmentStartTimestamp);
    item.segmentEndTimestamp = parseInt(item.segmentEndTimestamp);

function round2(num) { return Math.round(num * 100) / 100.0; }

exports.getProrationResult = getProrationResult;


Socotra does not make any guarantee about how proration items are batched. If there are ten proration items to be processed, the plugin may be called once with the list of all ten, or it could be called multiple times with a subset processed on each call.

Legacy Proration

If the proration plugin is not implemented, the system will behave as follows:

During endorsements and cancellations, Socotra allocates premium to each coverage period using a single method, so all calculations are consistent.

  • If periods start and end at 00:00:00 (midnight), actual-millisecond proration is the same as actual-day

  • When allocating premium to billing periods, Socotra assigns the same amount to each whole billing period and then uses actual-millisecond proration for partial billing periods.

For up-front, weekly, and every other week payment schedules, Socotra will use milliseconds-based proration. For other schedules, Socotra will use monthly-based proration based on the number of months (see below).

Month Counting

Consider the following scenario where a cancellation is processed before the end of the policy term:

  • The policy period is from June 13th for a one year term

  • The total premium for the year is $1200

  • The policyholder requests a cancellation effective September 19th

Resulting calculations:

  1. The remaining coverage period is from June 13th until September 19th, which is 3 months and 6 days.

  2. Since September 13th to October 13th is 30 days, the coverage period is 3 + 6/30 = 3.2 months long.

  3. 3.2 months will be used for monthly proration.