Schedules

Warning

This feature is currently in beta and may be subject to change, before using it in production please contact your Socotra representative.

Overview

Schedules are purpose-built to support insurance products that need to manage very large lists of like-typed items such as fleets of vehicles, property inventories, or collections of valuable articles. These lists can contain tens or even hundreds of thousands of items. Schedules allow insurers to efficiently collect, manage, and rate these items as part of the policy record, without sacrificing performance or clarity.

Schedules are especially relevant for:

  • Commercial Auto (e.g., listing 10,000+ fleet vehicles)

  • Homeowners (e.g., scheduled personal property)

  • Commercial Property (e.g., inventories of buildings or contents)

Each item in a schedule is structured, ratable (if needed), and independently addressable, while being logically grouped under a parent policy element (such as a Fleet or Location).

Use Cases

  • Fleet Management: Commercial Auto policies can include a schedule of hundreds of thousands of vehicles, each individually priced and editable.

  • Property Schedules: Warehouses or commercial buildings can manage long lists of insured contents with granular data capture.

  • Non-ratable Schedules: Policies can include schedules of beneficiaries, dependents, or other tracked data that doesn’t influence premium, but needs to be persisted and auditable.

Note

Similar use cases can also be implemented leverging conventional elements for the data structure, however these are not as performant and we strongly recommend using schedules for lists of over 2000 items. A system imposed limitation will likely be imposed in a future release. Such changes will be announced in advance to allow for migration.

Key Capabilities

  • Add schedules to any policy element, of any category & type, and at any level (e.g., per Fleet or Location as modeled using policyLines, exposureGroups, or exposures)

  • Each schedule supports:

    • Arbitrary numbers of schedule items (tested up to 500,000 per policy)

    • Custom structured data per schedule type

    • Support multiple like-type and/or unique schedule types per policy

    • Automatic generation of unique item identifiers (locators)

    • Addition, modification, and removal of items, individually or in bulk

    • Persist and access granular rates for multiple charge types on each schedule item

  • Schedule item types are fully configurable and can be reused across products

  • High-performance API support for pricing, quoting, and data extraction

Configuration

Schedules are associated with an element within the product data model. To configure a schedule, the element definition includes a schedule entry identifying the type of items the schedule will contain:

"Fleet": {
  "charges": ["CollisionPremium", "LiabilityPremium"],
  "schedule": "Vehicle"
}

Schedule item types are defined globally in the configuration schema:

"schedules": {
  "Vehicle": {
   "data": {
     "year": {},
     "make": {},
     "model": {}
   }
   "resetOnRenewal" : true // Optional, defaults to false, used to ensure that the schedule is cleared on renewal
  }
}

Only one schedule instance per element instance on a quote or policy is supported. As a result, the schedule type will be consistent across all instances of a given element type. Multiple unique schedule types can be defined and leveraged as long as the parent element type is also unique.

Data Structure

Schedule types leverage extension data, and just like elements can support deeply nested strcutures and inheritance. However, for performance reasons, the bulk upload of schedule items via CSV is limited to flat data structures with primitive typed fields.

Charges and Pricing

Each schedule item can be rated independently. As the rating process executes, the following steps are performed:

  • A RatingRegistry persists the pre-aggregation rating data for each schedule item for future reference (via method within the rating plugin)

  • All schedule item rates aggregated per charge type (via method within the rating plugin)

    • A “whole schedule” rate is computed as the sum of all individual item rates by charge type and from this a single synthetic charge is created (automatically by the system)

    • If both schedule and element-level charges of the same type exist, they are summed into a single synthetic charge (automatically by the system)

Example: If a Fleet contains 10,000 scheduled vehicles, each with a rate of 23.5 for the collisionPremium charge type, the synthetic charge applied to the Fleet post rating will have a rate equal to the sum of the individual scheduled item’s rates:

{ "collisionPremium": { "rate": 235000.00 } }

Only the synthetic (aggregated) charges are submitted to billing, not each individual scheduled item, ensuring optimal billing performance even for large schedules.

Plugin Interfaces

Given the complexity and performance requirements of schedules, the system provides specific plugin interfaces to handle the rating and data management:

Schedule Stream: The schedule itself is not passed to the plugin as part of the quote or transaction request. Instead the plugin can access the schedule via the SchedulesFactory and generate a stream of items for processing using the .stream() method.

// Quote Request
// Fetch locator for the fleet element in the quote
ULID fleetElementLocator = segment.element().elements().stream()
                    .filter(e -> "FleetQuote".equals(e.type()))
                    .map(Element::staticLocator)
                    .findFirst().orElseThrow();

Schedule schedule = SchedulesFactory.getQuoteSchedule(quote, fleetElementLocator)
Stream<VehicleScheduleItem> vehiclesStream = schedule.stream();

// Transaction Request
// Fetch locator for the fleet element in the transaction
ULID fleetElementLocator = segment.element().elements().stream()
                    .filter(e -> "FleetPolicy".equals(e.type()))
                    .map(Element::staticLocator)
                    .findFirst().orElseThrow();
Schedule schedule = SchedulesFactory.getTransactionSchedule(request.transaction(), fleetElementLocator)
Stream<VehicleScheduleItem> vehiclesStream = schedule.stream();

Rating Registry: The rating plugin can create a RatingRegistry to persit a granular view of the rating items for each charge type of each item in the schedule. The registry’s input parameter is a RatingItem, the same as is used for other rating operations.

// Create a rating registry for the quote
RatingRegistry registry = RatingRegistryFactory.createFor(quote, tripReport);

// Create a rating registry for the transaction
RatingRegistry registry = RatingRegistryFactory.createFor(request.transaction(), tripReport);

Consuming Schedule Stream: The stream of schedule items can be processed using the standard Java Stream API which allows for efficient processing of large datasets without loading everything into memory at once. Here a lambda expression is used to process each item:

tripsStream.map(vehicle -> rateVehicle(vehicle))
        .filter(Objects::nonNull)
        .flatMap(List::stream)
        .forEach(registry::register);

Here, the following happens:

  1. Each vehicle in the stream is processed by the rateVehicle method, which returns a list of RatingItem objects.

  2. The filter operation removes any null results from the rating.

  3. The flatMap operation flattens the list of lists into a single stream

  4. Finally, each RatingItem is registered in the RatingRegistry via the register method.

Aggreating Schedule Items Rates: Once rates for schedule items has completed, the rating registry can be used to aggregate the rates for each charge type across all items in the schedule.

// Aggregate rates for each charge type, stream to a list and add to the RatingItems list to be returned from the rating plugin
ratingItems.addAll(registry.aggregate().stream().toList());

API Usage

Schedules are fully supported across all policy lifecycle stages and are subjcet to the same data goverence as other policy elements.

Quotes

Add items to schedule
addScheduleItems
PUT /policy/{tenantLocator}/quotes/{locator}/schedules/{staticElementLocator}
    Request Parameters:
    NamePositionTypeRequired
    tenantLocatorpathuuidrequired
    locatorpathstringrequired
    staticElementLocatorpathstringrequired
    Security Group:quotes   Permissions:write,schedule-add
AddScheduleItemRequest
required
data map<string,object>

API requests to add items to a schedule are limited to 500 items

Upload a CSV of schedule items
uploadScheduleItems
POST /policy/{tenantLocator}/quotes/{locator}/schedules/{staticElementLocator}
    Request Parameters:
    NamePositionTypeRequired
    tenantLocatorpathuuidrequired
    locatorpathstringrequired
    staticElementLocatorpathstringrequired
    Request:file
    Security Group:quotes   Permissions:write,schedule-add

CSV for bulk upload of schedule items only support flat item data structures i.e. no nested objects in the schedule definition.

Delete an item from schedule
deleteScheduleItems
DELETE /policy/{tenantLocator}/quotes/{locator}/schedules/{staticElementLocator}
    Request Parameters:
    NamePositionTypeRequired
    tenantLocatorpathuuidrequired
    locatorpathstringrequired
    staticElementLocatorpathstringrequired
    Request:string[]
    Response:void
    Security Group:quotes   Permissions:write,schedule-delete

Delete individual items from a schedule by specifying their locator within the string array of the request.

Update a schedule item
updateScheduleItems
PATCH /policy/{tenantLocator}/quotes/{locator}/schedules/{staticElementLocator}
    Request Parameters:
    NamePositionTypeRequired
    tenantLocatorpathuuidrequired
    locatorpathstringrequired
    staticElementLocatorpathstringrequired
    Security Group:quotes   Permissions:write,schedule-update
PatchScheduleItemRequest
required
locator string
removeData map<string,object>
setData map<string,object>

Transactions

Add items to schedule
addTransactionSchedule
PUT /policy/{tenantLocator}/transactions/{locator}/schedules/{staticElementLocator}
    Request Parameters:
    NamePositionTypeRequired
    tenantLocatorpathuuidrequired
    locatorpathstringrequired
    staticElementLocatorpathstringrequired
    Security Group:transactions   Permissions:write,schedule-add
AddScheduleItemRequest
required
data map<string,object>

API requests to add items to a schedule are limited to 500 items

Upload a CSV of schedule items
uploadTransactionSchedule
POST /policy/{tenantLocator}/transactions/{locator}/schedules/{staticElementLocator}
    Request Parameters:
    NamePositionTypeRequired
    tenantLocatorpathuuidrequired
    locatorpathstringrequired
    staticElementLocatorpathstringrequired
    Request:file
    Security Group:transactions   Permissions:write,schedule-add

CSV for bulk upload of schedule items only support flat item data structures i.e. no nested objects in the schedule definition.

Delete an item from schedule
deleteTransactionSchedule
DELETE /policy/{tenantLocator}/transactions/{locator}/schedules/{staticElementLocator}
    Request Parameters:
    NamePositionTypeRequired
    tenantLocatorpathuuidrequired
    locatorpathstringrequired
    staticElementLocatorpathstringrequired
    Request:string[]
    Response:void
    Security Group:transactions   Permissions:write,schedule-delete

Delete individual items from a schedule by specifying their locator within the string array of the request.

Update a schedule item
updateTransactionSchedule
PATCH /policy/{tenantLocator}/transactions/{locator}/schedules/{staticElementLocator}
    Request Parameters:
    NamePositionTypeRequired
    tenantLocatorpathuuidrequired
    locatorpathstringrequired
    staticElementLocatorpathstringrequired
    Security Group:transactions   Permissions:write,schedule-update
PatchScheduleItemRequest
required
locator string
removeData map<string,object>
setData map<string,object>

Data & Reporting

API

Rating registries can be retrived in CSV format via the API to access the pre-aggregation rating data for each schedule item.

Get Rating Registry
getRatingRegistry
GET /plugin/{tenantLocator}/ratingregistries/{category}/{locator}/{elementLocator}
    Request Parameters:
    NamePositionTypeRequired
    tenantLocatorpathuuidrequired
    Accept-Encodingheaderstring?optional
    categorypathEnum quote | transactionrequired
    locatorpathstringrequired
    elementLocatorpathstringrequired
    Response:StreamingResponseBody<string>
    Security Group:ratingregistries   Permission:read

Data Lake

Schedules and Rating Registries are planned to be supported in an upcoming release of the Data Lake.

See Also