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:
- Change policy status - For example, mark an active policy as cancelled.
- Change policy balance - For example, increase a policy's premium.
- Change policy balance - For example, reduce a policy's outstanding balance.
- Trigger custom notification event - For example, trigger a custom email or SMS when a benefit is terminated.
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 name | Definition |
|---|---|
name | string. 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 incamelCaseIn the
update_policyaction object, the names of the properties under the data object are specified incamelCase. These properties correspond tosnake_casefield names on the policy object. For example,sumAssuredin the data object corresponds tosum_assuredon 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:
- Construct the new module object from the existing policy module object, which is passed to the function as
policy.module. - 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 name | Corresponding policy field | Definition |
|---|---|---|
monthlyPremium | monthly_premium | integer. The amount, in cents, of the monthly premium, as written on the policy schedule. |
basePremium | base_premium | integer. The amount, in cents, of the minimum allowed monthly premium fee. This includes risk pricing and platform fees. |
billingAmount | billing_amount | integer. 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. |
billingDay | billing_day | integer 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. |
sumAssured | sum_assured | integer. The amount, in cents, of the total value insured. May be excluded for group scheme policies. |
module | module | object. Custom module-specific fields stored against the policy. |
Top-level properties
Property name | Definition |
|---|---|
|
|
|
In the case of |
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 name | Definition |
|---|---|
name | string. Specifies the action to be performed. Must equal one of the predefined action names. |
amount | integer. The amount, in cents, with which to change the policy balance. |
description | string. The description of the ledger entry that will be created to debit or credit the policy. |
currency | string. 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
update_claim_module_dataOverview
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
dataobject are preserved - Fields in your
dataobject overwrite existing fields with the same key - New fields in your
dataobject 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:
afterPolicyLinkedToClaimafterClaimApprovedafterClaimBlockUpdatedbeforeClaimSentToReviewafterClaimSentToReviewbeforeClaimSentToCaptureafterClaimSentToCaptureafterClaimClosed
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
- 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.
- Merge behavior: The data is merged, not replaced. To remove a field, you would need to explicitly set it to
nullor handle removal differently. - Validation skipped: The update is performed with
skipValidation: true, so any module data can be stored without schema validation. - 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 specifiedActions are executed in the same order as specified in the
actionsarray 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 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
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 name | Definition |
|---|---|
name | string. 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 |
Updated about 11 hours ago