Counters Integration Point

The primary uses of this integration point are; (1) to provide other adjudication engines with current adjudication limit counts, (2) to provide information that can be used to generate periodic counter statements, (3) to allow other adjudication engines to submit increments and decrements to adjudication limits and (4) to enable counters offsets, e.g. when an account is migrated from another system onto OHI Claims Adjudication.

An increment to a limit counter is referred to as "consumption".A decrement is referred to as negative consumption.

Design Principles

External interfaces will determine when request messages are sent and what data they contain.

The service provided by the integration point described in this guide is restricted to:

  • calendar year based limits

  • plan year based limits

  • annual limits

  • sliding window limits

  • lifetime limits

  • first claim based limits

Regime counters, authorization counters, case based adjudication limits, counters related to claims and provider limits are not accessed by this integration point. The batch operations provided by the Counters Integration Point are examples of Long Running Operations through REST.

Write Consumption Online

Request

The HTTP POST request to: http://[hostName]:[portNumber]/[api-context-root]/limitconsumptions enables external systems to write consumption on counters.

Write consumption request messages have the following structure:

{
   "limitCode" : "",
   "familyCode" : "",
   "aggregationLevel" : "",
   "serviceDate" : "",
   "numberOfUnits" : "",
   "withdrawn" : "",
   "excludeFromCarryOver" : "",
   "providerGroupStatus" : "",
   "externalId" : "",
   "description" : "",
   "transactionSourceCode" : "",
   "referenceCode" : "",
   "" : {
      "code" : "",
   }
   "amount" : {
      "currency" : "",
      "value" : ""
   },
   "provider" : {
      "code" : "",
      "flexCodeDefinitionCode" : ""
   }
}

Note that the transaction date-time (attribute of consumption) is not sent in, but set automatically to the current date and time while processing the write consumption request.

In case the request fails to specify an attribute required for processing that request, the response will contain an explanatory message (see Error Messages section).

Creating Consumption

Before the consumption can be created checks will be performed if the codes provided in the request (limit, insurable entity, aggregation level, provider, currency and transaction source) are known. If a code is unknown, the consumption creation process stops and an error message is returned in the response (see Error Messages section).

Besides checking whether the limit with the given code exists, that limit will also be checked to see whether it is not case based (with reference Case) or referring to a claim (with reference Single Claim) and that the information that is needed to select a counter or create a new counter if the applicable counter does not yet exist, is provided in the request. For insurable entity level limits an insurable entity is required; for family level limits a family code is required. If the limit is case based or specific to a claim or the information needed to select or create a counter is not provided, the process stops and an error message is returned in the response.

A consumption can only be created if the correct value (amount, number, withdrawn indicator) based on the limit type (amount, number or service days) is provided in the request. If that is not the case, the process stops and an error message is returned in the response.

If all of the above verified correctly, the correct counter based on the limit code and insurable entity (for insurable entity level limits) or family code (for family level limits) is selected. If the counter does not exist, it is created based on the provided information. Counters for insurable entity level limits get a reference to the provided person or object (insurable entity). For family level limits the provided family code is stored on the counter without a reference to the provided person or object (if an insurable entity is provided it will only be stored on the consumption). After the counter has been selected or created, the limit consumption is created and the applicable counter periods are updated:

  • A limit consumption is created for the selected or newly created counter, with the amount/qty, currency, service date, withdrawn indicator, exclude from carry over indicator, provider, aggregation level, insurable entity, provider group status, external id, description, transaction source and reference as specified in the request

    • Note that the maximum amount/number/service days is unspecified (null) on external consumptions and that external consumption is always finalized (preliminary indicator unchecked and transaction date-time set)

    • If the currency code is not provided for amount type limits, it is derived:

      • If the limit counter does not yet exist or it exists without any limit counter periods, the consumption is created with the default currency code

      • If a limit counter period that the consumption counts towards exists (based on the search as specified below), then the current amount currency code of the counter period is taken

      • If no limit counter periods exist that the consumption counts towards, but other limit counter periods do exist for the applicable counter, then the current amount currency code of the most recent counter period is taken

  • The system searches for applicable existing counter periods (only if the counter already existed) for the limit. If the limit is specified as a sub limit to other limit(s), the system also fetches the counter periods of all the other (composite) limits towards which it counts; based on:

    • Service date, provider, aggregation level, currency and exclude from carry over indicator of the consumption

    • Start date, end date, carry over start date, other products carry over start date, provider, aggregation level and current amount currency specified on the counter periods; note that: whether a consumption counts towards a counter period or not is determined by the following conditions:

      • Consumption with an unspecified provider counts towards counter periods of all providers

      • Consumption with a specified provider also counts towards counter periods with an unspecified provider (for limits that count across providers)

      • Consumption with an unspecified aggregation level counts towards counter periods of all aggregation levels

        • Note that if both a carry over period and an other products carry over period are specified and the consumption falls in both periods, it still only counts once towards the counter period

      • Consumption with a specified aggregation level also counts towards counter periods with an unspecified aggregation level (for limits that count across products [1])

      • Consumption that falls in the carry over period only counts towards the counter period if the aggregation level of the consumption is unspecified or if it matches the aggregation level of the counter period for limits that count per product aggregation level; for limits that count across products** all consumption (regardless of the aggregation level) that falls in the carry over period counts towards the counter period

      • Consumption that falls in the other products carry over period only counts towards the counter period if the aggregation level of the consumption is unspecified or if it does not match the aggregation level of the counter period

      • Consumption only counts towards counter periods with the same currency (consumption currency matches counter period current amount currency)

[1]

  • The current amount/number of units/service days on the retrieved counter periods is updated (if applicable); note that:

    • The maximum amount/number of units/service days is not updated, because external consumption is not evaluated against a maximum

    • It is possible that no counter periods are found; in that case the consumption will not yet (it will always be taken into account when new claim lines are processed) count towards any counter period (no new counter periods are created by this mechanism)

  • The version on the counter is incremented by 1

    • If the counter periods of the composite limit is updated, then its counter is also updated by 1

Limits With a Carry Over Period

Writing consumption to a limit with a carry over period may result in a consumption that counts towards two different counter periods.

The composite limit counter periods are also considered, if the limit to which the consumption being written to is specified as a sub limit.

If the excludeFromCarryOver attribute in the request is set to "No" (or left unspecified) and the service date is within a carry over period, the consumption counts:

  • towards the counter period that captures the service date between its start and end date.

  • towards the counter period that captures the service date between its carry over start date and the day prior to its start date.

To clarify consider the following scenario. Configured is a 1 year calendar based limit with a carry over period of two months. Currently, two counter periods exist:

  • the counter period for 2007 which has a carry over start date 11/1/2006, start date 1/1/2007 and end date 12/31/2007

  • the counter period for 2008 which has a carry over start date 11/1/2007, start date 1/1/2008 and end date 12/31/2008

A consumption request comes in with the excludeFromCarryOver attribute set to "No" and service date 12/4/2007. This date is both in the carry over period of the 2008 counter period, as well as the period of the 2007 counter period. As a result, the consumption counts towards both counter periods.

If a consumption request comes in with the excludeFromCarryOver attribute set to "Yes" and service date 12/4/2007 the consumption will only count towards the 2007 counter period.

Note that if the limit counts per product aggregation level, only the consumption of the same (or unspecified) product aggregation level is counted; if the limit counts across product aggregation levels all consumption is counted, regardless of the product aggregation level.

Note that the above specified behavior also applies to the Other Products Carry Over Period. Consumption of other (or unspecified) product aggregation levels during the carry over period is also counted for the next full period of the new product aggregation level; consumption of the same product aggregation level is not counted.

Two Consumptions

Response

When the consumption is created successfully, HTTP status code '201: Created' is returned. Additionally the response will set a HTTP Location header to point to the generic HTTP API representation of the created consumption.

Write Consumption Batch

Request

This request enables the handling of multiple write consumption requests in one go. Because the volume of data can become quite extensive, the input for this process will come from a so called data file set. For more information about how to create a data file set please refer to Data File Set Integration Point.

Consumption batch elements that are contained in the datafile(s) that are part of the input data file set have the following structure - in here the <consumptionList> is the root element of an individual datafile.

<consumptionList>
  <consumption
    elementId=""
    limitCode=""
    familyCode=""
    aggregationLevel=""
    serviceDate=""
    numberOfUnits=""
    withdrawn=""
    excludeFromCarryOver=""
    providerGroupStatus=""
    externalId=""
    description=""
    transactionSourceCode=""
    referenceCode="">

    <amount currencyCode="">
      {value}
    </amount>
    <provider flexCodeDefinitionCode="" code=""/>
  </consumption>
  ...
</consumptionList>

For more specifics of how individual consumption elements are imported, see the previous description of #Creating Consumption[Creating Consumption]. Note that there is a required "elementId" attribute in each request element, to allow for correlation between an error message and a specific consumption. This information will be part of the data file set response that will be produced by the write consumption batch process.

In the remainder of this description we assume that an input data file set containing at least one datafile with a structure as was outlined above has been created. In order to initiate the consumption import process a HTTP POST request to: http://[hostName]:[portNumber]/[api-context-root]/writeconsumptionbatches has to be submitted. A write consumption batch (initiation) request has the following structure:

{
   "dataFileSetCode" : "..."
}

The system responds with HTTP 201 (Created) and a location header for the write consumption batch.

Note that it is also possible to submit the equivalent XML payload, contained by the root element: WriteConsumptionBatchInput.

In the above request the dataFileSetCode refers to the data file set that contains the datafile(s) with consumption records that need to be imported.

Response

As is described in Long Running Operations through REST there are multiple ways in which one can get the response/result of this long running operation. Typically though one would opt for using notification events.

For Write Consumption Batch a notification message can be sent out to a pre-configured endpoint. The notification endpoint can be configured on 'ohi.activityprocessing.notification.endpoint.CONSUMPTION_IMPORT' or to a more generic endpoint: ohi.activityprocessing.notification.endpoint.

If the notification endpoint is configured on the specific: CONSUMPTION_IMPORT, all other properties are also fetched based on CONSUMPTION_IMPORT or else defaults are used. Similarly if the endpoint for the notification is configured without the specific code, then all other properties are fetched on a generic usecase code 'ActivityNotificationClient' Please see section Outbound RESTful Service Invocations in Integration Guide for the process and more properties. The notification message has the following/common structure:

<notification correlationId="" workId="{activityId}" status="">
   <links>
     <link rel='file' href='http://host:port/api/datafilesets/{datafilesetcode}/datafile/{datafilecode}/data'/>
     <link rel='file' href='http://host:port/api/datafilesets/{datafilesetcode}/datafile/{datafilecode}/data'/>
     ...
    </links>
</notification>

Effectively the data file set holds a reference of the result of the Write Consumption Batch. Note that in case one uses a polling approach to follow the progress and/or performs collection queries over writeconsumptionbatch resources, for completed Write Consumption Batch operations the data file set link will be there. For these one can get to the actual stream of data by using the Data File Set Integration Point operations.

As said the data file set will hold the result of the Write Consumption Batch operation. Every individual datafile will have a generic structure:

<consumptionResponse>
   <resultMessages result="S">
      <resultMessage code="GEN-FILE-006">
         The total number of successfully processed records is {0}
      </resultMessage>
   </resultMessages>
   <resultMessages result="F" elementId="{elementId}">
      <resultMessage code="{error code}">
         {error text}
      </resultMessage>
   </resultMessages>
</consumptionResponse>

In this generic structure the message GEN-FILE-006 is used to inform about the number of records (in this case consumption elements) that were successfully imported into the system. If there were problems in importing (individual) consumption records those will be also contained in the datafile. A sample of that is included in the description above. These elements which failed importing, will include the elementId as a reference to the consumption element that resulted in an error additionally it will contain the {error code} and {error text} to further detail the problem that the system detected.

Read Consumption Batch

With this operation the user is given the ability to read consumptions that are contained by the system. This can be viewed as a consumption report. Because the volume of data returned can become quite extensive, the result of this process will be a datafile set.

Request

In order to initiate the consumption import process a HTTP POST request to: http://[hostName]:[portNumber]/[api-context-root]/readconsumptionbatches has to be submitted. A read consumption batch (initiation) request has the following structure

{
   "limitCodes" : [ {code}, {code}, ... ],
   "transactionStartDateTime" : {
      "value" : "..."
   },
   "transactionEndDateTime" : {
      "value" : "..."
   }
}

Note that it is also possible to submit the equivalent XML payload, contained by the root element: ReadConsumptionBatchInput. In that case the limitCodes element becomes a container of limit codes, with each individual limit code contained by a <value> element.

The consumption details are retrieved using the above specified selection criteria. All criteria are optional. Which consumptions are returned depends on what is specified in the request:

  • If only a list of limitCodes is specified, then all consumptions for the specified limits are returned

  • If only transactionStartDateTime and/or transactionEndDateTime are specified, then all consumptions with a transaction or reversal date-time in the specified period are returned

    • if no transactionStartDateTime is specified and only the transactionEndDateTime is specified, then all consumptions up-to the end period are returned

    • if no transactionEndDateTime is specified and only the transactionStartDateTime is specified, then all consumption from the start period are returned

  • If both limitCodes and a combination or both of the transactionStartDateTime and transactionEndDateTime is specified, then consumptions matching all combined criteria will be returned

  • If no criteria are specified, all consumptions are returned

  • Consumption for limits with the reference Case or Single Claim is not returned

  • The system responds with HTTP 201 (Created) and a location header for the read consumption batch.

Note that:

  • Both the internal consumption, created due to claims processing, and the external consumption, created through this integration point is returned

  • Only finalized consumption is returned

Response

For Read Consumption Batch a notification message is sent out to a pre-configured endpoint.The endpoint to send notification can be configured using 'ohi.ReadConsumptionBatch.endpoint.request.If the endpoint requires Authentication, please use Authentication Use Case: ReadConsumptionBatch to set authentication.Please see section Outbound RESTful Service Invocations in Integration Guide for the process and more properties.The notification message has the following/common structure:

<notification correlationId="" workId="{activityId}" status="">
   <links>
     <link rel='file' href='http://host:port/api/datafilesets/{datafilesetcode}/datafile/{datafilecode}/data'/>
     <link rel='file' href='http://host:port/api/datafilesets/{datafilesetcode}/datafile/{datafilecode}/data'/>
     ...
    </links>
</notification>

Effectively the data file set holds a reference of the result of the Read Consumption Batch.Note that in case one uses a polling approach to follow the progress and/or performs collection queries over readconsumptionbatch resources, for completed Read Consumption Batch operations the data file set link will be there.For these one can get to the actual stream of data by using the Data File Set Integration Point operations.The file hypermedia link is contained in the event as a convenience to allow for direct datastream access to the Consumption Data File.More information about that actual data contained in the data file set is described in the section about consumption data file.

Consumption Data File

The read consumption batch process creates a datafile contained in a data file set with the following structure:

<consumptionList>
  <consumption
    claimCode=""
    claimLineCode=""
    numberOfUnits=""
    maximumNumber=""
    maximumServiceDays=""
    withdrawn=""
    reversed=""
    excludeFromCarryOver=""
    serviceDate=""
    transactionDateTime=""
    aggregationLevel=""
    providerGroupStatus=""
    description=""
    referenceCode=""
    transactionSourceCode=""
    externalId=""
    reserved=""
    expirationDate=""
    subLimitCode="">

    <amount currencyCode="">
      {value}
    </amount>
    <maximumAmount currencyCode="">
      {value}
    </maximumAmount>
    <provider flexCodeDefinitionCode="" code=""/>
    <counter
      limitCode=""
      limitDescription=""
      familyCode="">

      <counterPeriodList>
        <counterPeriod
          startDate=""
          endDate=""
          carryOverStartDate=""
          otherProductsCarryOverStartDate=""
          aggregationLevel=""
          maximumNumber=""
          maximumServiceDays=""
          currentNumber=""
          currentServiceDays="">
          <maximumAmount currencyCode="">
            {value}
          </maximumAmount>
          <currentAmount currencyCode="">
            {value}
          </currentAmount>
          <provider flexCodeDefinitionCode="" code=""/>
        </counterPeriod>
      </counterPeriodList>
    </counter>
  </consumption>
  ...
</consumptionList>

For every consumption the counter periods that the consumption counts towards are returned.Note that:

  • Consumption with an unspecified provider counts towards counter periods of all providers

  • Consumption with a specified provider also counts towards counter periods with an unspecified provider (for limits that count across providers)

  • Consumption with an unspecified aggregation level counts towards counter periods of all aggregation levels

  • Consumption with a specified aggregation level also counts towards counter periods with an unspecified aggregation level (for limits that count across products)

  • Consumption that falls in the carry over period only counts towards the counter period if the aggregation level of the consumption is unspecified or if it matches the aggregation level of the counter period for limits that count per product aggregation level; for limits that count across products all consumption (regardless of the aggregation level) that falls in the carry over period counts towards the counter period

  • Consumption that falls in the other products carry over period only counts towards the counter period if the aggregation level of the consumption is unspecified or if it does not match the aggregation level of the counter period

  • Consumption only counts towards counter periods with the same currency (consumption currency matches counter period current amount currency)

  • If the limit being read is a composite limit, then the consumptions of the sub limits are selected:

    • if they are not for the same claim line as the composite limit consumptions (i.e. do not refer to the composite limit)

    • and have the same provider group status as specified in the sub limit setup

    • Note:

      • a sub limit consumption follows the same guidelines as specified above in determining whether it counts towards a counter period or not

      • when a composite limit counts per product, sub limit configuration specifies if the sub limit consumption counts for the same product or across product.

        • For a composite limit that counts per product, the sub limit setup may apply specifies if the sub limit consumption counts towards the same product or all products.When a sub limit is configured to count per product, the sub limit consumption with aggregation level unspecified or if it matches the aggregation level of the counter period for the composite limit will count towards the counter period of the composite.For a sub limit configured to count across products all consumption (regardless of the aggregation level) that falls in the counter period of the composite counts towards it.

When no consumptions exist based on the specified criteria the response contains an empty <consumptionList> element.When a consumption does not count towards any counter period the <counterPeriodList> element is not returned for that consumption.

The way that reversed consumption is returned, needs to be transformed from the table structure.Consider the following example.The following table represents how reversed consumption is stored in the database:

Claim Claim Line Amount Service Date Transaction Date Reversal Date

CL01

1

$ 100

2/15/10

2/25/10

3/31/10

If the requested transaction period is 2/1/10 through 4/1/10 then the response is:

Claim Claim Line Amount Service Date Transaction Date

CL01

1

$ 100

2/15/10

2/25/10

CL01

1

- $ 100

2/15/10

3/31/10

If the requested transaction period is 3/1/10 through 4/1/10 then the response is:

Claim Claim Line Amount Service Date Transaction Date

CL01

1

- $ 100

2/15/10

3/31/10

If the requested transaction period is 2/1/10 through 3/1/10 then the response is:

Claim Claim Line Amount Service Date Transaction Date

CL01

1

$ 100

2/15/10

2/25/10

After this transformation, the consumptions are ordered by transaction date, ascending.This way, it is easiest to show the deltas.Also, it is in line with the way that external consumption is shown perforce.Although not shown in the example, the number of units are shown with a minus sign as well in exactly the same way.

Error Messages

The following situations will cause a request message to fail:

  • The insurable entity (combination of code and type code) is unknown;

  • The limit code is unknown;

  • The provider (combination of code and flex code definition code) is unknown;

  • The aggregation level is unknown;

  • The start date-time is greater than the end date-time for the transaction period.

In case of a request to write consumption, additional information may be required depending on how the limit is configured:

  • Recording consumption for an insurable entity based limit requires an insurable entity, but no insurable entity is specified;

  • Recording consumption for a family based limit requires a family code, but no family code is specified;

  • Recording consumption for an amount based limit, but no amount is specified;

  • Recording consumption for a number based limit, but no number of units is specified.

In case of a request to write consumption, in some situations it is not allowed to write consumption:

  • Recording consumption for a service days based limit, but also specifying an amount or a number;

  • Recording consumption for an amount or number based limit, but also specifying that the consumption is withdrawn;

  • Recording consumption for a limit that is related to an adjudication case (the limit has reference case) or a claim (the limit has reference single claim);

The above specified situations result in the following error messages:

Code Severity Message

CLA-IP-LIMI-003

Fatal

Limit code {code} is unknown

CLA-IP-LIMI-006

Fatal

Provider identified by code {code} and flex code definition code {code} is unknown

CLA-IP-LIMI-011

Fatal

Either amount or number should be specified unless the limit type is service days (in which case both amount and number should be left blank)

CLA-IP-LIMI-012

Fatal

Insurable entity is required for insurable entity level limits

CLA-IP-LIMI-013

Fatal

Family code is required for family level limits

CLA-IP-LIMI-014

Fatal

The provided value does not comply with limit type {type}

CLA-IP-LIMI-018

Fatal

It is not possible to write consumption to a limit related to an adjudication case or a claim

CLA-IP-LIMI-024

Fatal

Start date-time {start date-time} cannot be greater than the end date-time {end date-time} of the transaction period

CLA-IP-LIMI-025

Fatal

Withdrawn consumption is only allowed if the limit type is service days

CLA-IP-LIMI-026

Fatal

Aggregation level {aggregation level} is unknown

CLA-IP-LIMI-027

Fatal

Insurable entity identified by code {code} and type {code} is unknown

In addition, other messages not specific to the Counters Integration Point may be returned as well.

Please refer to Response Messages for more details.


1. when a consumption is created for a limit, that acts as sub limit to other limit(s). The sub limit setup specifies if the sub limit consumption counts per product or across products in context of the composite limit