HomeGuidesAPI ReferenceChangelog
Log In
Guides

Block and Index Rates

Model fixed energy blocks, indexed market pricing, delivery points, and sellback provisions for contracted supply rates.

Model fixed energy blocks, indexed market pricing, delivery points, and sellback provisions for contracted supply rates.

Block and index rates are contracted supply rates with two components: a fixed price for one or more usage blocks, and an indexed market price for usage above those blocks.

Use this guide after you understand how to model a basic contracted rate. For the core contracted-rate fields and simpler examples, see Contracted Rates in Deregulated Markets.

How block and index rates work

In a simple contracted rate, you can replace the customer's normal supply rate with a flat custom rate, such as $0.05 per kWh. In deregulated markets, third-party supply contracts can use more complex structures. One common structure is a block and index rate.

A block and index rate has two components: a fixed price for the first part of the customer's monthly energy usage, and a variable rate tied to an index price for the rest. The advantage of this structure is that you usually get a fixed, low rate for most of your energy usage. The downside is that, if you don't use enough energy to consume your entire block allocation, you still have to pay for it.

Here are the details of the block and index rate that we're going to set up for our account:

  • For the first 2,000 kWh of hourly usage, set a flat rate of $0.05 per kWh.
  • For the next 600 kWh of hourly usage, the flat rate increases to $0.06 per kWh.
  • After that, index the rate to PJM's hourly real-time price.

The Account Cost Calculation request is more complex for block and index contracted rates. Use this rateInputs snippet:

{  
  "rateInputs": [  
    {  
      "rateName": "Multiple Block and Index Rate",  
      "tariffBookRateName": "Multiple Block and Index Rate",  
      "chargeClass": "CONTRACTED",  
      "chargeType": "CONSUMPTION_BASED",  
      "chargePeriod": "HOURLY",  
      "transactionType": "BUY",  
      "variableRateKey": "hourlyPricingRealTimePJM",  
      "variableRateSubKey": "51291",  
      "rateBands": [  
        {  
          "hasConsumptionLimit": true,  
          "consumptionUpperLimit": 2000,  
          "rateAmount": "0.05",  
          "rateUnit": "BLOCK",  
          "isCredit": false  
        },  
        {  
          "hasConsumptionLimit": true,  
          "consumptionUpperLimit": 2600,  
          "rateAmount": "0.06",  
          "rateUnit": "BLOCK",  
          "isCredit": false  
        },  
        {  
          "hasConsumptionLimit": true,  
          "rateAmount": null,  
          "rateUnit": "COST_PER_UNIT",  
          "isCredit": false  
        }  
      ]  
    }  
  ]  
}  

In this request, note:

  • The first two bands use rateUnit: "BLOCK".
  • The final band uses rateUnit: "COST_PER_UNIT" and rateAmount: null to fall back to the market index.
  • consumptionUpperLimit values are cumulative, not incremental.

There are a few important tariff properties:

  • "chargePeriod":"HOURLY" tells the API that, for the block portions of the tariff, the consumption limits are defined hourly, and, once we get to the index portion of the tariff, we're going to update the rate hourly.
  • "transactionType":"BUY" means that we're going to charge the customer for this energy. This is as opposed to the "SELL" option, which would result in a credit.
  • "variableRateKey":"hourlyPricingRealTimePJM" specifies the particular index that we're going to be buying energy from. In this case, it's PJM.
  • "variableRateSubKey":"51291" specifies the delivery point. Within PJM's market, there are a number of delivery points. Here, we're specifying the AECO delivery point, which has the identifier 51291.

The rateBands are more complex than they are for a flat contracted rate because there are two blocks and an index instead of a single flat rate for all usage.

  • "consumptionUpperLimit":2000 and "consumptionUpperLimit":2600 specify block thresholds. The second block has a consumptionUpperLimit value of 2,600 even though it only represents 600 kWh of usage. This is because consumptionUpperLimit refers to total consumption, not incremental consumption. For example, if you had three blocks of 300 kWh, 200 kWh, and 200 kWh, specify their consumptionUpperLimit values as 300, 500, and 700.
  • "rateUnit":"BLOCK" tells the API that this portion of the bill is fixed. Even if the customer does not use all 2,600 kWh that they've been allocated, they still have to pay for the entire block.
  • The final rate band has rateAmount: null and rateUnit: "COST_PER_UNIT". This tells the API to fall back to the index defined by variableRateKey and variableRateSubKey for the rest of the customer's usage during that billing period.

This defines a block and index rate.

Get more indexes

We defined the index using variableRateKey. In the example above, we used hourlyPricingRealTimePJM and then defined a variableRateSubKey to specify the delivery point. The combination of these two values, the index and the delivery point, determines exactly how much this customer will pay for their energy.

The Arcadia API has more indexes and more delivery points than just these. To see them all, use the following request:

GET /rest/public/properties/?keySpace=market

This will return a list of all indexes in our database.

Delivery points

Some, though not all, market indexes have different prices for different delivery points. The one that we used in this example, hourlyPricingRealTimePJM, has 20. To specify your delivery point, add variableRateSubKey in addition to variableRateKey.

Use the following request, replacing hourlyPricingRealTimePJM with the index that you're interested in:

GET /rest/public/properties/hourlyPricingRealTimePJM/

This will return a list of all available variableRateSubKey values for this index. This response snippet has been shortened to show the relevant delivery point choices:

{  
  "status": "success",  
  "count": 1,  
  "type": "PropertyKey",  
  "results": [  
    {  
      "keyName": "hourlyPricingRealTimePJM",  
      "displayName": "Hourly Pricing Real Time PJM",  
      "family": "pjm",  
      "keyspace": "market",  
      "description": "Hourly Pricing Real Time PJM",  
      "dataType": "LOOKUP",  
      "choices": [  
        {  
          "displayValue": "AECO",  
          "value": "51291",  
          "dataValue": "51291",  
          "likelihood": null  
        },
        /* edited for length */

    {
      "displayValue": "RECO",
      "value": "7633629",
      "dataValue": "7633629",
      "likelihood": null
    }
  ]
}

To specify your delivery point, use the dataValue field of that delivery point in the list of choices for the value of your variableRateSubKey property.

Block and index rates with sellback

Some block and index contracts allow the customer to sell any unused kWh back to their energy supplier at the index price. This is called a “sellback” provision. In these contracts, the customer pays the block price and receives a credit for any unused kWh at the index price. The same index price will be used for both kWh in excess of the block and crediting unused kWh within the block.

To create a sellback block and index rate, mirror the rate structure of a standard block and index rate but with a different rate unit: BLOCK_SELL_BACK.

Here’s an example with only the rateInputs snippet of the full calculator request:

{
  "rateInputs":[
      {
         "rateName":"Sellback Block and Index Rate",
         "tariffBookRateName":"Sellback Block and Index Rate",
         "chargeClass":"CONTRACTED",
         "chargePeriod":"HOURLY",
         "transactionType":"BUY",
         "variableRateKey":"hourlyPricingRealTimePJM",
         "variableRateSubKey":"51291",
         "rateBands":[
            {
               "hasConsumptionLimit":true,
               "consumptionUpperLimit":2000,
               "rateAmount":"0.05",
               "rateUnit":"BLOCK_SELL_BACK",
               "isCredit":false
            },
            {
               "hasConsumptionLimit":true,
               "rateAmount":null,
               "rateUnit":"COST_PER_UNIT",
               "isCredit":false
            }
         ]
      }
   ]
}

Next steps