Usage

When invoicing usage-based subscriptions, you need to record usage data into Kill Bill. Note that Kill Bill is not designed to be a metering system, so it shouldn't contain all data points. Instead, it expects that you record a usage summary on a daily basis (1 API call per subscription per day). For a telco company, for instance, instead of recording all phone calls, you should only record the number of minutes effectively used for each day.

For more information, see our catalog usage documentation and our invoice usage documentation.

Usage Resource

There are several resource objects associated with usage in Kill Bill. These are shown below.

SubscriptionUsageRecord, along with its components UnitUsageRecord and UsageRecord, is used to enter the daily usage summary into the system.

SubscriptionUsageRecord:

Name Type Generated by Description
subscriptionId string system UUID for the subscription
trackingId string user User's tracking Id for this usage record
unitUsageRecords list user List of UnitUsageRecord (see next)

UnitUsageRecord:

Name Type Generated by Description
unitType string user Type of unit represented
usageRecords list user List of UsageRecord for this unit (see next)

UsageRecord:

Name Type Generated by Description
recordDate string user Date/DateTime for this record in yyyy-mm-dd/yyyy-mm-ddThh:mm:ssZ format
amount number user Amount of usage for this record

RolledUpUsage, along with its component RolledUpUnit, is used to maintain the cumulative record of usage over a specified period of time.

RolledUpUsage:

Name Type Generated by Description
subscriptionId string system UUID for the subscription
startDate string system starting datetime for this record
endDate string system ending datetime for this record
rolledUpUnits list system List of RolledUpUnit (see next)

RolledUpUnit:

Name Type Generated by Description
unitType string system type of unit represented
amount number system total amount of usage of this unit

Usage

The APIs in this group support recording and retrieving usage data points.

Record usage for a subscription

Records the daily amount of usage of a specified set of unit types for a given subscription

HTTP Request

POST http://127.0.0.1:8080/1.0/kb/usages

Example Request:

# With Date

curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
     -d '{"subscriptionId":"365987b2-5443-47e4-a467-c8962fc6995c", "trackingId": "my-unique-tracking-id", "unitUsageRecords":[{"unitType":"chocolate-videos","usageRecords":[{"recordDate":"2013-03-14","amount":1}]}]}' \
    "http://localhost:8080/1.0/kb/usages"

# With DateTime and amount as decimal
curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
     -d '{"subscriptionId":"f2d142c3-0157-4f86-a27a-3f0f64d71b2b", "trackingId": "t2", "unitUsageRecords":[{"unitType":"stones","usageRecords":[{"recordDate":"2023-02-07T10:00","amount":20.5}]}]}' \
    "http://localhost:8080/1.0/kb/usages"
import org.killbill.billing.client.api.gen.UsageApi;
protected UsageApi usageApi;

UUID subscriptionId = UUID.fromString("2daf08aa-3a32-45d7-9d75-9c667391f994");

UsageRecord usageRecord1 = new UsageRecord();
usageRecord1.setAmount(BigDecimal.ONE);
usageRecord1.setRecordDate(new DateTime("2023-02-27"));

UnitUsageRecord unitUsageRecord = new UnitUsageRecord();
unitUsageRecord.setUnitType("bullets");
unitUsageRecord.setUsageRecords(List.of(usageRecord1));

SubscriptionUsageRecord usage = new SubscriptionUsageRecord();
usage.setSubscriptionId(subscriptionId);
usage.setUnitUsageRecords(List.of(unitUsageRecord));

usageApi.recordUsage(usage, requestOptions);

user = "demo"
reason = nil
comment = nil

usage_record = KillBillClient::Model::UsageRecordAttributes.new
usage_record.amount = 1
usage_record.record_date = "2013-03-14"

unit_usage_record = KillBillClient::Model::UnitUsageRecordAttributes.new
unit_usage_record.unit_type = "chocolate-videos"
unit_usage_record.usage_records = []
unit_usage_record.usage_records << usage_record

result = KillBillClient::Model::UsageRecord.new
result.subscription_id = "365987b2-5443-47e4-a467-c8962fc6995c"
result.unit_usage_records = []
result.unit_usage_records << unit_usage_record

result.create(user, nil, nil, options)
usageApi = killbill.api.UsageApi()

usageRecord = UsageRecord(record_date='2023-09-05', amount=1)
unitUsageRecord = UnitUsageRecord(unit_type='hours',usage_records=[usageRecord])

subscriptionUsageRecord = SubscriptionUsageRecord(subscription_id='dc89f346-bc55-46ee-8963-1b666d8fea50', tracking_id="t4", unit_usage_records=[unitUsageRecord])

usageApi.record_usage(subscriptionUsageRecord,
                      created_by='demo',
                      reason='reason',
                      comment='comment')
const api: killbill.UsageApi = new killbill.UsageApi(config);

const usageRecord: UsageRecord = {amount: 4, recordDate: "2023-09-17"};
const unitUsageRecord: UnitUsageRecord = {unitType: "hours", usageRecords:[usageRecord]};
const subscriptionUsageRecord: SubscriptionUsageRecord = {subscriptionId: "dc89f346-bc55-46ee-8963-1b666d8fea50", unitUsageRecords: [unitUsageRecord]};

api.recordUsage(subscriptionUsageRecord, 'created_by');
$apiInstance = $client->getUsageApi();

$xKillbillCreatedBy = "user";
$xKillbillReason = "reason";
$xKillbillComment = "comment";

$usageRecord = new UsageRecord();
$usageRecord -> setAmount(2);
$usageRecord -> setRecordDate('2023-09-15');

$unitUsageRecord = new UnitUsageRecord();
$unitUsageRecord -> setUnitType('hours');
$unitUsageRecord -> setUsageRecords(array($usageRecord));

$subscriptionUsageRecord = new SubscriptionUsageRecord();
$subscriptionUsageRecord -> setSubscriptionId('dc89f346-bc55-46ee-8963-1b666d8fea50');
$subscriptionUsageRecord -> setUnitUsageRecords(array($unitUsageRecord));

$apiInstance->recordUsage($subscriptionUsageRecord, $xKillbillCreatedBy, $xKillbillReason, $xKillbillComment);

Request Body

A SubscriptionUsageRecord.

Query Parameters

none

Response

If successful, returns a status code of 201 and an empty body.

Retrieve usage for a subscription and unit type

Retrieves the usage record for a given subscription, for a specified period of time and a specified unit type

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/usages/{subscriptionId}/{unitType}

Example Request:

curl -v \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Accept: application/json" \
    "http://localhost:8080/1.0/kb/usages/365987b2-5443-47e4-a467-c8962fc6995c/chocolate-videos?startDate=2012-08-25&endDate=2013-08-26"
import org.killbill.billing.client.api.gen.UsageApi;
protected UsageApi usageApi;

UUID subscriptionId = UUID.fromString("365987b2-5443-47e4-a467-c8962fc6995c");

String unitType = "chocolate-videos";
LocalDate startDate = new LocalDate("2012-08-25");
LocalDate endDate = new LocalDate("2013-08-26");
Map<String, String> NULL_PLUGIN_PROPERTIES = null;

RolledUpUsage retrievedUsage = usageApi.getUsage(subscriptionId, 
        unitType, 
        startDate, 
        endDate, 
        NULL_PLUGIN_PROPERTIES,
        requestOptions);
subscription_id = "365987b2-5443-47e4-a467-c8962fc6995c"
start_date = "2012-08-25"
end_date = "2013-08-26"
unit_type = "chocolate-videos"

usages = KillBillClient::Model::RolledUpUsage.find_by_subscription_id_and_type(subscription_id,
                                                                      start_date,
                                                                      end_date,
                                                                      unit_type,
                                                                      options)
TODO
const api: killbill.UsageApi = new killbill.UsageApi(config);

const subscriptionId = 'dc89f346-bc55-46ee-8963-1b666d8fea50';
const unitType = 'hours'
const startDate = '2023-09-01';
const endDate = '2023-09-30';

const response: AxiosResponse<killbill.RolledUpUsage, any> = await api.getUsage(subscriptionId, unitType, startDate, endDate);
$apiInstance = $client->getUsageApi();

$subscriptionId = "dc89f346-bc55-46ee-8963-1b666d8fea50";
$unitType = "hours";
$startDate = new DateTime("2023-09-01");
$endDate = new DateTime("2023-09-30");
$pluginProperty = array("pluginProperty_example");

$result = $apiInstance->getUsage($subscriptionId, $unitType, $startDate, $endDate, $pluginProperty);

Example Response:

{
  "subscriptionId": "365987b2-5443-47e4-a467-c8962fc6995c",
  "startDate": "2012-08-25",
  "endDate": "2013-08-26",
  "rolledUpUnits": [
    {
      "unitType": "chocolate-videos",
      "amount": 10.5
    }
  ]
}

Query Parameters

Name Type Required Default Description
startDate date yes none Date/DateTime of oldest data point to retrieve (see below) in yyyy-mm-dd/yyyy-mm-ddThh:mm:ssZ format
endDate date yes none Date/DateTime of newest data point to retrieve (see below) in yyyy-mm-dd/yyyy-mm-ddThh:mm:ssZ format
pluginProperty array of strings false omit list of plugin properties, if any

Response

If successful, returns a status code of 200 and a RolledUpUsage object.

Retrieve usage for a subscription

Retrieves the usage record for a given subscription, for a specified period of time and all unit types.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/usages/{subscriptionId}

Example Request:

curl -v \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Accept: application/json" \
    "http://localhost:8080/1.0/kb/usages/365987b2-5443-47e4-a467-c8962fc6995c?startDate=2012-08-25&endDate=2013-08-26"
import org.killbill.billing.client.api.gen.UsageApi;
protected UsageApi usageApi;

UUID subscriptionId = UUID.fromString("365987b2-5443-47e4-a467-c8962fc6995c");

LocalDate startDate = new LocalDate("2012-08-25");
LocalDate endDate = new LocalDate("2013-08-26");
Map<String, String> NULL_PLUGIN_PROPERTIES = null;
RolledUpUsage retrievedUsage = usageApi.getAllUsage(subscriptionId, 
        startDate, 
        endDate, 
        NULL_PLUGIN_PROPERTIES,
        requestOptions);
subscription_id = "365987b2-5443-47e4-a467-c8962fc6995c"
start_date = "2012-08-25"
end_date = = "2013-08-26"

usages = KillBillClient::Model::RolledUpUsage.find_by_subscription_id(subscription_id,
                                                             start_date,
                                                             end_date,
                                                             options)
TODO
const api: killbill.UsageApi = new killbill.UsageApi(config);

const subscriptionId = 'dc89f346-bc55-46ee-8963-1b666d8fea50';
const startDate = '2023-09-01';
const endDate = '2023-09-30';

const response: AxiosResponse<killbill.RolledUpUsage, any> = await api.getAllUsage(subscriptionId, startDate, endDate);
$apiInstance = $client->getUsageApi();

$subscriptionId = "dc89f346-bc55-46ee-8963-1b666d8fea50";
$startDate = new DateTime("2023-09-01");
$endDate = new DateTime("2023-09-30");
$pluginProperty = array("pluginProperty_example");

$result = $apiInstance->getAllUsage($subscriptionId, $startDate, $endDate, $pluginProperty);

Example Response:

{
  "subscriptionId": "365987b2-5443-47e4-a467-c8962fc6995c",
  "startDate": "2012-08-25",
  "endDate": "2013-08-26",
  "rolledUpUnits": [
    {
      "unitType": "chocolate-videos",
      "amount": 1
    }
  ]
}

Query Parameters

Name Type Required Default Description
startDate date yes none Date/DateTime of oldest data point to retrieve (see below) in yyyy-mm-dd/yyyy-mm-ddThh:mm:ssZ format
endDate date yes none Date/DateTime of newest data point to retrieve (see below) in yyyy-mm-dd/yyyy-mm-ddThh:mm:ssZ format
pluginProperty array of strings false omit list of plugin properties, if any

Response

If successful, returns a status code of 200 and a RolledUpUsage object.