Actions

Define automated actions triggered by policy lifecycle events or scheduled functions

Overview

Actions can be returned by lifecycle hooks and scheduled functions in the product module code. If returned, they are added to the Root platform's job queue for execution.

Three categories of actions are currently supported. Actions can be used to make the following changes related to existing policies:

Actions objects are returned inside an array, allowing multiple actions to be returned by the same lifecycle hook or scheduled function.

The action object

The action to be queued is specified using the name property of the action object. The name of the action must match one of the predefined actions listed in this guide.

Actions that update policy data require a second property, the data object. This data will be used to update the existing policy data.

Actions that change the policy balance require three additional properties: the amount by which to change the balance, a description for the ledger entry, and the currency corresponding to the amount.

Example

The example below uses the after payment failed lifecycle hook to define custom logic for handling failed payments. In this example, the sum assured covered under the policy is reduced, and the policy status is changed to not_taken_up. (This example is for illustration only and the logic specifying under which conditions these actions are returned has been omitted).

const afterPaymentFailed = ({ policy, payment }) => {
  // Custom logic omitted
  const actions = [
    {
      name: "update_policy",
      data: {
        sumAssured: policy.sum_assured - 1000,
      },
    },
    { name: "mark_policy_not_taken_up" },
  ];
  return actions;
};

Change policy status

Actions can be queued to change a policy's status to active, lapsed or not_taken_up.

Activate policy

This action changes a policy's status to active (for example if a policy has been lapsed or cancelled). Only the name of the action is required.

{ name: 'activate_policy'}

Cancel policy

This action changes a policy's status to cancelled (for example as part of implementing custom lapse rules for a product). Please see Cancel policy for the attribute options

{ 
  name: 'cancel_policy',
  reason: '<reason>'
  cancellation_requestor: 'client',,
  cancellation_type: 'Alternate product'
}

Lapse policy

This action changes a policy's status to lapsed (for example as part of implementing custom cancel rules for a product). Only the name of the action is required.

{ name: 'lapse_policy' }

Mark policy not taken up

This action changes a policy's status to not_taken_up (for example as part of implementing custom not taken up checks for a product). Only the name of the action is required.

{ name: 'mark_policy_not_taken_up' }

Properties

Property nameDefinition
namestring. Specifies the action to be performed. Must equal one of the predefined action names.

Update policy data

You can use the update_policy action to update selected standard fields (see the supported data properties section below) on a policy, as well as the module data. The values of these fields are set when the policy is issued via the policy issue hook.

Note: Only the fields that are to be updated on the policy need to be specified in the data object. Any properties not specified will not be changed.

Read more about the standard fields included on all policies in the policy object.

📘

Data object property names are in camelCase

In the update_policy action object, the names of the properties under the data object are specified in camelCase. These properties correspond to snake_case field names on the policy object. For example, sumAssured in the data object corresponds to sum_assured on the policy.

Update standard policy fields

The standard fields that can be updated on the policy are defined within the supported data properties section.

Example

The snippet below represents an update of the policy's sum assured.

{
  name: 'update_policy',
  data: {
    sumAssured: newSumAssured,
  }
}

For a full example of updating the policy premium, see the scheduled functions guide.

Update module data

Changing the module field using this action will replace the entire module object on the policy. We recommend the following approach to update the policy module data:

  1. Construct the new module object from the existing policy module object, which is passed to the function as policy.module.
  2. Replace the entire module object by returning the updated module object as data.module.

Example

The snippet below shows how the product specific extraction_benefit field can be updated on the module object.

const removeExtractionBenefit = ({ policy }) => {
  const newModule = {
  	...policy.module,
    extraction_benefit: false,
  };
  
  return [
    {
      name: 'update_policy',
      data: {
        module: newModule,
      }
    }
  ];
}

Supported data properties

Data object property nameCorresponding policy fieldDefinition
monthlyPremiummonthly_premiuminteger. The amount, in cents, of the monthly premium, as written on the policy schedule.
basePremiumbase_premiuminteger. The amount, in cents, of the minimum allowed monthly premium fee. This includes risk pricing and platform fees.
billingAmountbilling_amountinteger. The amount, in cents, that will be billed on the next billing run. If less than monthly_premium, the difference is seen as a 'discount.' Can be updated to between base_premium and monthly_premium, inclusive.
billingDaybilling_dayinteger or null. The day of month on which the policy is billed. Should be between 1 and 31, or null. If it falls on a day that does not exist in the month (for example, 31 in February) the policy will be billed on the last day of the month. Setting this value to 31 will ensure that the policy is billed on the last day of every month.
sumAssuredsum_assuredinteger. The amount, in cents, of the total value insured. May be excluded for group scheme policies.
modulemoduleobject. Custom module-specific fields stored against the policy.

Top-level properties

Property name

Definition

name

  • string_. Specifies the action to be performed. Must equal one of the predefined action names.

data

  • object_. New data with which to update existing policy data.

In the case of update_policy, this object will reference standard top-level policy fields.

Change policy balance

Debit policy

This action creates a new ledger entry debiting the policy. If the policy has an outstanding (negative) balance, this action will increase the outstanding balance in absolute terms. If the policy is in credit (has a positive balance), the balance will be reduced.

{
  name: 'debit_policy',
  amount: 100000,
  description: 'Reactivation penalty',
  currency: 'USD'
}

Credit policy

This action creates a new ledger entry crediting the policy. If the policy has an outstanding (negative) balance, this will reduce the outstanding balance in absolute terms. If the policy is in credit (has a positive balance), this action will increase it.

{
  name:'credit_policy',
  amount: policy.balance,
  description: 'Forgive outstanding policy balance',
  currency: 'USD'
}

Properties

Property nameDefinition
namestring. Specifies the action to be performed. Must equal one of the predefined action names.
amountinteger. The amount, in cents, with which to change the policy balance.
descriptionstring. The description of the ledger entry that will be created to debit or credit the policy.
currencystring. Three-digit currency code representing the currency in which the policy will be debited or credited. Must match the product module currency. E.g. "USD" or "ZAR".

Update claim data

update_claim_module_data

Overview

The update_claim_module_data action allows you to update the custom module data stored on a claim from within claim-related lifecycle hooks. It works similarly to update_policy_module_data but targets the claim's module data instead of the policy's.


Action Schema

{
  name: 'update_claim_module_data',
  data: {
    // Object with fields to merge into claim.module
  }
}

Properties:

  • name (string, required): Must be 'update_claim_module_data'
  • data (object, required): An object containing the fields to merge into the claim's existing module data

How It Works

When this action is executed, it merges the provided data object into the existing claim.moduleData:

await updateClaim(organizationId, environment, metadata, claim.id, {
  skipValidation: true,
  module: {
    ...claim.moduleData,          // Existing claim module data
    ...productModuleAction.data,  // Your new data (overwrites matching keys)
  },
});

This means:

  • Existing fields not in your data object are preserved
  • Fields in your data object overwrite existing fields with the same key
  • New fields in your data object are added

Lifecycle Hooks That Can Use This Action

Only lifecycle hooks that receive a claim object can use update_claim_module_data. Using it from other hooks will throw an error.

Supported hooks:

  • afterPolicyLinkedToClaim
  • afterClaimApproved
  • afterClaimBlockUpdated
  • beforeClaimSentToReview
  • afterClaimSentToReview
  • beforeClaimSentToCapture
  • afterClaimSentToCapture
  • afterClaimClosed

Example Usage

Example 1: Update claim module data after a claim block is updated

const afterClaimBlockUpdated = ({ policy, policyholder, claim, block_key }) => {
  // Calculate some derived data based on claim blocks
  const incidentDate = claim.block_states?.incident_date?.value;
  const claimAmount = claim.block_states?.claim_amount?.value;
  
  // Store calculated values in claim module for later use
  return [
    {
      name: 'update_claim_module_data',
      data: {
        calculated_payout: claimAmount * 0.8, // 80% of claimed amount
        days_since_incident: moment().diff(moment(incidentDate), 'days'),
        last_updated: moment().format(),
      },
    },
  ];
};

Example 2: Track claim workflow state

const afterClaimSentToReview = ({ policy, policyholder, claim }) => {
  return [
    {
      name: 'update_claim_module_data',
      data: {
        review_started_at: moment().format(),
        workflow_stage: 'in_review',
        assigned_reviewer: null, // Will be set later
      },
    },
  ];
};

Example 3: Store policy benefit information when claim is linked

const afterPolicyLinkedToClaim = ({ policy, policyholder, claim }) => {
  // Capture relevant policy benefits at time of claim for audit trail
  return [
    {
      name: 'update_claim_module_data',
      data: {
        policy_benefits_at_claim: {
          sum_assured: policy.sum_assured,
          monthly_premium: policy.monthly_premium,
          cover_start_date: policy.start_date,
          main_life_cover: policy.module.main_life?.cover,
        },
        claim_linked_at: moment().format(),
      },
    },
  ];
};

Example 4: Combined with other actions

const afterClaimDecisionAcknowledged = ({ policy, policyholder, claim }) => {
  if (claim.approval_status === 'approved') {
    return [
      // Update claim module data
      {
        name: 'update_claim_module_data',
        data: {
          approved_at: moment().format(),
          approval_acknowledged: true,
        },
      },
      // Also trigger a notification
      {
        name: 'trigger_custom_notification_event',
        custom_event_key: 'claim_approved_notification',
        custom_event_type: 'claim',
        claim_id: claim.claim_id,
      },
    ];
  }
  return [];
};

Important Notes

  1. Claim context required: If you attempt to use this action from a hook that doesn't have a claim (e.g., afterPaymentSuccess), it will throw an error:
   Cannot run lifecycle hook action update_claim_module_data for lifecycle hook request {...} there is no claim specified.
   
  1. Merge behavior: The data is merged, not replaced. To remove a field, you would need to explicitly set it to null or handle removal differently.
  2. Validation skipped: The update is performed with skipValidation: true, so any module data can be stored without schema validation.
  3. Use for audit trails: This action is useful for storing audit information, calculated values, or workflow state that should be tracked on the claim itself.

Limitations - What This Action Cannot Do

This action can ONLY update the module field on a claim. It cannot modify any other claim properties.

Cannot update:

  • **status** (open, in_review, closed, etc.)
  • **approval_status** (approved, repudiated, goodwill, no_claim)
  • **claimant** details
  • **incident_date**
  • **incident_cause**
  • **blocks** or **block_states**
  • Any other top-level claim fields

Trigger custom notification event

📘

Actions are executed in the order specified

Actions are executed in the same order as specified in the actions array in the product module code. For example, if you first want to update the policy module data and then trigger a custom notification event, you should include the notification action as the last object in the array.

This action is used to trigger a custom notification event from the product module code.

{
  name: 'trigger_custom_notification_event',
  custom_event_key: 'policyholder_birthday',
  custom_event_type: 'policy',
  policy_id: policy.policy_id,
}

Properties

Property name

Definition

name

  • string_. Specifies the action to be performed. In this case, trigger_custom_notification_event.

custom_event_key

  • string_. The key of the custom event to trigger.

custom_event_type

  • string_. The type of the custom event to trigger. Must be one of [policy, payment_method, payment, claim].

policy_id
optional

  • string_. The UUID of the policy for which to trigger the notification. Required if custom_event_type is policy or payment_method, forbidden otherwise.

payment_id
optional

  • string_. The UUID of the payment for which to trigger the notification. Required if custom_event_type is payment, forbidden otherwise.

claim_id
optional

  • string_. The UUID of the claim for which to trigger the notification. Required if custom_event_type is claim, forbidden otherwise.

Archive Alteration Package

This action archives the policy alteration package specified. Only pending alteration packages can be archived.

{
  "name": 'archive_alteration_package',
  "alteration_package_id": "184fa9a3-f967-4a98-9d8f-57152e7cbe64"
	}
}

Properties

Property nameDefinition
namestring. Specifies the action to be performed. Must equal one of the predefined action names.
alteration_package_id__string__. The UUID of the policy alteration package to archive