# Availability



Overview [#overview]

Socotra can be configured to help manage the introduction and retirement of products, [data extensions](/configuration/data-extensions/overview), [policy elements](/features/policy-management/policy-elements), and [coverage terms](/features/policy-management/coverage-terms), supporting use cases like these:

* Retiring a product after a certain time, or for all new quotes.
* Specifying a future date after which certain elements can be added to policies.
* Automatically removing certain coverage terms on policy renewal.

Socotra's availability implementation has two fundamental characteristics:

1. Availability configuration can only be made on *optional* data elements, avoiding a range of edge cases and the need for migration solutions that would be needed if it were offered for required items as well. Data extension fields must have the `*` or `?` quantifiers to be eligible for availability configuration.
2. The platform enforces availability at the validation step, so any quotes, accounts, etc. that made it through that step prior to the deployment of a contradictory availability rule will not be blocked or otherwise invalidated; instead, you can implement more fine-grained handling for such cases in your plugin logic. You may also leverage [Data Lake](/features/reporting/datalake) to identify validated records you consider to be out of alignment with your latest availability specification.

A key benefit of Socotra's availability design is that such configuration updates are [always considered to be "safe"](/configuration/general-topics/redeployment#redeployment_safety).

The feature is not exclusive to policies and quotes, but can also be used for data extensions associated with other entities, including [accounts](/features/accounts), [payments](/features/billing/payments), and [disbursements](/features/billing/disbursements).

Configuration [#configuration]

Here is the `AvailabilityRef` configuration specification:

<ApiSchema name="AvailabilityRef" />

The specification supports three major "availability" concepts, which can be applied individually or in combination:

1. Availability: the time after which the item can be added
2. Retirement: the time at which the item cannot be added
3. Remove on Renewal: the time at which the item will be automatically stripped from new terms

The distinction between truly required and optional configuration properties follows an intuitive rule: if you opt in to one of these core availability concepts, you must provide the platform with enough information to determine a clear intent. For example, you could have an availability configuration that is as simple as this:

```javascript
{
    // ... other config ...,
    "availability": {
        "retireAfter": "2024-06-01T00:00:00+0000"
    }
}
```

In this case, the platform would understand that you merely want to retire the element as of a certain time, and will apply the default time basis `termStartTime`. If you were to <ApiLink name="fetchConfigDefinition">fetch the deployed datamodel</ApiLink>, you would see the equivalent configuration with explicit defaults:

```javascript
{
    // ... other config ...,
    "availability": {
        "availabilityTimeBasis": "termStartTime",
        "retireAfter": "2024-06-01T00:00:00Z",
        "retire": false,
        "retirementTimeBasis": "termStartTime",
        "removeOnRenewal": false
    }
}
```

The `retire` property is `false` since a specific retirement time is set. Both the `retire` and `removeOnRenewal` boolean properties are `true` only when retirement or removal on renewal are meant to be applied for all time, respectively.

<Callout>
  Removal on renewal is not available for products. Deployment attempts with such configuration will fail.
</Callout>

Examples [#examples]

Setting a product to retire after a certain time [#setting-a-product-to-retire-after-a-certain-time]

Suppose you have a product that should no longer be allowed on new quotes taking effect after midnight on June 1, 2025. In the product configuration, you could set availability like this:

```javascript
{
    // ... other config ...,
    "availability": {
        "retireAfter": "2025-06-01T00:00:00+0000"
    }
}
```

Following configuration deployment, any attempt to validate a quote with `startTime` after `2025-06-01T00:00:00+0000` will fail with a validation error:

<span id="product_availability_error_example" />

```javascript
{
    // ...,
    "validationResult": {
        "validationItems": [
            {
                "elementType": "FloodProtectionQuote",
                "locator": "01JGBXEQ0BS4KCNNM6NAG9JXDT",
                "errors": [
                    "Product 'FloodProtection' expired based on the availability config"
                ]
            }
        ],
        "success": false
    }
}
```

<Callout>
  As mentioned earlier, any quotes with `startTime` after `2025-06-01T00:00:00+0000` that had been validated prior to the introduction of this availability constraint will not be blocked from issuance.
</Callout>

Retiring a product [#retiring-a-product]

If you want to retire a product regardless of the effective time of the quote, you could set validation configuration as follows:

```javascript
{
    // ... other config ...,
    "availability": {
        "retire": true
    }
}
```

After deploying this change, an attempt to validate any quote with this product will fail with an error [like the one shown above](#product_availability_error_example). Any existing validated quotes with that product are still considered valid since they had been validated prior to the imposition of the availability constraint.

<Callout>
  Socotra's transaction model means that availability rules will apply to reinstatement. For example, if an issued `SomeProduct` policy is cancelled, followed by configuration deployment that retires `SomeProduct`, attempts to validate a reinstatement of the policy will fail.
</Callout>

Making an element available to new policies starting after a certain time [#making-an-element-available-to-new-policies-starting-after-a-certain-time]

In the following example, a "Bodily Injury" coverage is set to be available on policy terms starting after June 1, 2024:

```javascript
{
    "displayName" : "Bodily Injury",
    "charges" : [ "Bodily_Injury" ],
    "abstract" : false,
    "availability": {
        "availableAfter": "2024-06-01T00:00:00Z"
    }
}
```

An attempt to validate a quote with this element starting before midnight on June 1, 2024 will fail:

```javascript
{
    // ...,
    "validationResult": {
        "validationItems": [
            {
                "elementType": "LocationQuote",
                "locator": "01JGCJ64YVYTAV5YAQES2AYHTY",
                "errors": [
                    "Element 'BodilyInjury' not available yet based on the availability config"
                ]
            }
        ],
        "success": false
    }
}
```

Since the availability time basis is the default, `termStartTime`, this quote could be validated and issued without the element, but later add "Bodily Injury" in a renewal term, assuming that the renewal term starts on or after June 1, 2024. If the availability configuration had specified `policyStartTime` as the `availabilityTimeBasis`, then "Bodily Injury" could not be added to the policy, even as part of a renewal term after the specified availability date.

Note that by setting `availableAfter` to a sufficiently early time, you can effectively say "make this element available to any new policies".

Automatically removing certain coverage terms on policy renewal [#automatically-removing-certain-coverage-terms-on-policy-renewal]

In the following example, a coverage called "GeneralLimit" is set for removal on any quote renewal:

```javascript
{
    "type" : "splitLimit",
    "options" : {
        "cv5001000200" : {
        "displayName" : "$5,000/$3,000/$8,000",
        "value" : 1700,
        "tag" : "500/1000/200"
        },
        // ...,
    },
    "availability": {
        "removeOnRenewal": true
    }
}
```

As a result, a renewal transaction for the policy will automatically have a change instruction to remove "GeneralLimit":

```javascript
{
    "locator": "01JGEDKZMVZ36VCTKX6QC9YT2R",
    "transactionType": "renewal",
    "transactionCategory": "renewal",
    // ...,
    "changeInstructions": [
        // ...,
        {
            "locator": "01JGEDMGA5VEM1DABWA94S9CAZ",
            "action": "modify",
            "staticLocator": "01JGEDHJEAGWQN3Q10FGW6FDR6",
            "removeCoverageTerms": {
                "GeneralLimit": "cv5001000200"
            }
        },
        // ...,
    ],
    // ...,
}
```

Of course, `removeOnRenewalAfter` works in a similar way, but only applies for renewal transactions taking effect after the provided datetime.

Additional Considerations [#additional-considerations]

Inheritance [#inheritance]

Availability follows simple rules for elements and products using inheritance:

1. If the parent item has an availability option, it will be used for child items.
2. Availability configuration on a child item completely supersedes any parent availability configuration.

Non-Policy Entities [#non-policy-entities]

Time basis settings on data extensions associated with non-policy entities such as accounts, payments, and disbursements always resolve to "now" at validation, even if some other value is provided. For example, if you have a data extension on a field set with `availableAfter` of `"2024-06-01T00:00:00Z"`, you should expect the platform to compare that value against the moment that account validation is attempted.

Any "remove on renewal" configuration on such entities will not have any impact.


## API Reference

AvailabilityRef
Specifies availability. At least one of availableAfter, retireAfter, retire, removeOnRenewalAfter, or removeOnRenewal must be set.
Properties:
  availableAfter (datetime)
  availabilityTimeBasis (Enum policyStartTime | termStartTime, required) — default: TermStartTime
  retireAfter (datetime)
  retire (boolean) — default: false
  retirementTimeBasis (Enum policyStartTime | termStartTime, required) — default: TermStartTime
  removeOnRenewalAfter (datetime)
  removeOnRenewal (boolean) — default: false