# Metrics



Socotra's Metrics APIs provide visibility into a variety of key business metrics across the entirety of your environment, without the need for any pre-configuration. Reports can be run on GWP, Quote & Policy counts among others, with options to aggregate on a variety of levels including tenants, products and time periods.

Overview [#overview]

The following metrics are currently available;

* Gross Written Premium
* Issued Policies
* Priced Quotes
* New Business Conversion Rate
* Issued Renewals
* Expired Policies
* Renewal Rate

These metric reports can be consumed as raw data via API, or as visualizations via the Reporting Workbench, both of these options also support the export of result data in csv format.

API Usage [#api-usage]

Regardless of the metric, the desired time range that the query should cover must be specified in the request body via the mandatory `startTime` and `endTime` parameters. All other request parameters described below are optional.
Time filtering behaves inclusive on the left, exclusive on the right, meaning `startTime : 2024-01-01` and `endTime : 2025-01-01` will include all of **Jan 1st 2024**, and none of **Jan 1st 2025**.

<Callout type="warn">
  While metric requests can cover future periods, the service design has been optimized for retrospective reporting. Result sets for rates that are future looking are susceptible to distortion and are not recommended or supported.
</Callout>

Within the requests there are a variety of ways to specify how the returned results should be structured, these options generally fall into two categories, **aggregations** and **filters**.

Aggregations [#aggregations]

Aggregation parameters afford control over how the result set is broken out into different groups, the options here include;

* **periodic** - takes a single value from the enum list of `none`, `day`, `week`, `month`, `quarter` or `year`.
  * Will break results into brackets of time per the periodic specified. e.g. a request for Gross Written Premium over a one year time frame with the `periodic` of `month` will return a result set of 12 values, each showing the Gross Written Premium for the respective month. The sum of the amounts in the result set will equal the amount returned had the request been made without any `periodic` specified.

* **groupByTenant** - takes a boolean flag `true` or `false`.
  * If set to true the results are broken out into sets representing each tenant that contributed data. e.g. In an implementation with multiple tenants deployed, a request for Gross Written Premium over a one year time frame with the `groupByTenant` flag set to `true` will return a result set with values for each distinct tenant. The sum of the amounts in the result set will equal the amount returned had the request been made without the `groupByTenant` flag set.

* **groupByProduct** - takes a boolean flag `true` or `false`.
  * If set to true the results are broken out into sets representing each product that contributed data. e.g. In an implementation with multiple products deployed, a request for Gross Written Premium over a one year time frame with the `groupByProduct` flag set to `true` will return a result set with values for each distinct product. The sum of the amounts in the result set will equal the amount returned had the request been made without the `groupByProduct` flag set.

<Callout>
  Aggregation parameters are not mutually exclusive and can be used in combination.
</Callout>

Filters [#filters]

Filter parameters afford control over what whether data from certain sources should be included or suppressed from the result sets, the options here include;

* **tenantType** - takes a single value from the enum list of `production` or `test`.
  * Will ensure that result data is only sourced from tenants of the type specified in the request.

* **tenantLocators** - takes an array of tenant locators.
  * Will ensure that result data is only sourced from tenants specified in the request.

* **products** - takes an array of product names.
  * Will ensure that result data is only sourced from entities (quotes, policies, transaction, charges etc) associated with the products specified in the request.

* **currencies** - takes an array of ISO 4217 currency codes.
  * Only applicable to the GWP metric. Will ensure that a distinct result set per currency code specified will be included in the response (assuming that charges in that currency exist and are captured in the broader result set).

Backfill Zero [#backfill-zero]

Sparse data sets or requests that utilize more granular periodic values such as `day` or `week` are more likely to contain observation gaps in the result set. To de-burden direct UI consumption of the APIs from having to deal with observation gaps, the service supports a `backfillZeroes` query parameter in the endpoint url.
Default to false, if set to true the system will inject an observation with a value of `0` into the result set.

<Callout type="warn">
  In order to protect system performance there is a limit of 55 imposed for backfilling zeros that will apply to any sub-set of observations. When requesting a result set for a one year period, the system will support backfilling in combination with a periodic of `years`, `quarters`, `months` or `weeks`. A periodic of `days` in such cases is not supported because the number of observations will exceed 55.
</Callout>

<ApiSchema name="MetricRequest" />

<ApiSchema name="MetricResponse" />

<ApiSchema name="DataPoint" />

Metric Definitions [#metric-definitions]

Gross Written Premium [#gross-written-premium]

**Definition:** The sum of all charges of category `premium` attributed to transactions in state `issued` or `reversed` whose `issuedTime` falls within the specified period, with some adjustments to ensure historical immutability.

Charges in Socotra are generated during the processing of transactions, and they can be both positive and negative. The GWP metric for a period will include charges from all transactions; this includes new business, cancellation, reinstatement, renewal, and mid-term changes. Premium charges related to cancellation and mid-term changes may be negative.

To preserve historical immutability, two mechanisms govern how charges are attributed:

* For reversed transactions, which do not have explicit premium charges generated by the system upon reversal, reversal charges are materialized and booked at the `issuedTime` of the affecting (reversing) transaction rather than the original.
* For reapplied transactions (OOS scenarios), since the reapplication's `issuedTime` is copied from the original, the `issuedTime` of the aggregate transaction created by the OOS is used as the canonical reference instead.

These adjustments ensure that OOS and reversal transactions do not reach back and modify a closed period; instead, they produce a new, visible premium impact in the period in which they occur.

As a result, GWP for a period includes:

* Premium charges from all `issued` and `reversed` transactions, booked at their actual `issuedTime`. In OOS scenarios, reapplications of reversed transactions have their `issuedTime` copied from the original, reversed transaction; however, for the purposes of this calculation, the premium is booked at the `issuedTime` of the aggregate transaction created by the OOS.
* For any `issued` transaction that is later `reversed`, the original premium charges are negated and then materialized as explicit reversal charges, booked at the `issuedTime` of the reversing transaction rather than the original, reversed transaction.

Issued Policies [#issued-policies]

**Definition:** The count quotes whose `issuedTime` falls within the specified period.
Policies are created in Socotra when a quote is moved to the issued state.

Priced Quotes [#priced-quotes]

**Definition:** The count of quotes which reached the `priced`, or some subsequent, state within the specified period.
Quotes that meet this criteria but are subsequently `discarded` or `reset` will not be included in the count.

New Business Conversion Rate [#new-business-conversion-rate]

**Definition:** The proportion of **Priced Quotes** that go on to become **Issued Policies** within the specified period. More specifically the rate is calculated as the count of **Priced Quotes** in the specified period, divided by the count of **Issued Quotes** in that same specified period, where set of issued quotes is a subset of the identified priced quotes.
Within a result set, a priced quote that gets assigned to a certain period, but whose issuance falls in a subsequent period, will not contribute to the conversion rate of either period.

Issued Renewals [#issued-renewals]

**Definition:** The count quotes renewal transactions whose `issuedTime` falls within the specified period.
Policies are renewed in Socotra when a transaction of category `renewal` is moved to the issued state.

Expired Policies [#expired-policies]

**Definition:** The count of policies where the `endTime` of the latest term falls within the specified period.
If the `endTime` was set via a cancellation transaction, the policy is not counted as an expiry and will not be counted

Renewal Rate [#renewal-rate]

**Definition:** The proportion of policies **eligible** for renewal that went on to be renewed in within the specified period.
A policy is deemed eligible for renewal in a given period if either a) the policy was actually renewed in the specified period, or b) the `endTime` of the latest term falls within the specified period.

<Callout>
  For the renewal rate the periodic parameter is mandatory, if it is not set - exception will be raised.
</Callout>


## API Reference

MetricRequest
Properties:
  groupByProduct (boolean)
  groupByTenant (boolean)
  tenantLocators (uuid[])
  products (string[])
  tenantType (Enum test | production | retired | deleted)
  startTime (datetime, required)
  endTime (datetime, required)
  periodic (Enum none | day | week | month | quarter | year)
  currencies (string[])
  localStartDateAdjusted (date, required)
  localEndDateAdjusted (date, required)

MetricResponse
Properties:
  offset (integer, required)
  count (integer, required)
  startDate (date, required)
  endDate (date, required)
  periodic (Enum none | day | week | month | quarter | year, required)
  results (DataPoint[], required)

DataPoint
Properties:
  productName (string, required)
  tenantLocator (uuid, required)
  currency (string, required)
  dataPointStartDate (date, required)
  value (number, required)