
# Usage Balances Core Concepts

This section covers the core concepts of the Usage Balances object model.

This page covers the data model of the [Usage Balances API][usage-balances-api] (`GET /projects/{project}/usageBalances`). The Usage Balance API returns an "allowance meter" for data, voice and SMS consumption on a user plan and add-on basis, ideal for showing to users. For aggregated consumption records that can be sliced by time range, country, and roaming status see [Usage Records][usage-records-core-concepts].

## Getting Started with Usage Balances

Usage Balances give your app a single, pre-computed view of what each user has used and what they have left, broken down by the plans and add-ons the user has available to them. One API call returns consumed amounts, remaining amounts, and percentages for each allowance on a subscription.

### Common use cases

- **In-app usage display.** Render progress bars per allowance, labels per coverage region, and separation between base-plan and add-on entitlements, all from one response.
- **Threshold notifications and upselling.** React to the `usageBalance.thresholdReached` webhook event when a user crosses 50%, 70%, 90% and 100% of an allowance, allow you to prompt add-on purchases in your app or by sending push notifications.
- **Customer Support.** Verify users have successfully used their purchased plans and add-ons.

Here we describe the main concepts of the Usage Balance object model.

## Usage Balance vs. Allowance

An **Allowance** is the fixed definition what a product (plan or add-on) entitles a user to. A **Usage Balance** is the active "instance" of an Allowance, providing the consumption of data, voice and SMS _allowed_ by the product.

- **Allowance** = the entitlement (e.g. "10 GB of data included")
- **Usage Balance** = the meter (e.g. "4.2 GB used of 10 GB")

## The Usage Balance object

A Usage Balance is an activated instance of an [Allowance](#allowance), tied to a specific subscription, for a specific time window in the case of plans or to a specific add-on. It tracks how much of that Allowance has been consumed.

Usage Balances are created automatically when a [subscription][subscription] or [subscription add-on][addons-guide] _activates_. This means Usage Balances can exist before they are actually _used_. For example a user in the United States purchases a data roaming add-on before a trip to France; the Usage Balance will be created once the purchase is completed (activating the add-on) and show zero usage. Once the user lands in France, where the add-on applies, the Usage Balance will begin showing data consumption.

### How Balances Map to Allowances

Each Allowance belongs to a subscription plan or add-on. There can be up to three Allowances per plan or add-on; one each for data, voice and SMS, depending one how the plan or add-on has been configured.

In the case of add-ons, the relationship between Allowances and Usage Balances is one-to-one, because add-ons are not recurring.

For subscription plans, there can be a one-to-many relationship between Allowances and Usage Balances, as the plan may recur over multiple [subscription periods](#subscription-period). Generally [the Usage Balance API][usage-balances-api] will return the data, voice and SMS balances for the current subscription plan period, although this can be steered with the `subscriptionPeriod` query parameter.

### Usage Balance Fields

| Field | Type | Description |
|---|---|---|
| `object` | string | Always `"usageBalance"` |
| `id` | string | Unique identifier (prefixed `ubl_`) - see [ID Prefixes](#id-prefixes) |
| `allowance` | [Allowance](#allowance) | The Allowance (prefixed `alw_`) definition this balance tracks - see [ID Prefixes](#id-prefixes) |
| `subscription` | string | Subscription ID (`sub_`) this balance belongs to - see [ID Prefixes](#id-prefixes)|
| `source` | [Source](#source) | Where this balance comes from ([subscription period](#subscription-period) or add-on) |
| `unit` | string | `"bytes"`, `"seconds"`, or `"messages"` - see [Units](#units) |
| `used` | integer | Amount consumed so far, in [`unit`](#units) |
| `limit` | integer or null | Total available, in [`unit`](#units). `null` = [unlimited](#unlimited-allowances) |
| `remaining` | integer or null | Amount left, in [`unit`](#units) (`limit - used`). `null` if [unlimited](#unlimited-allowances) |
| `usedPercent` | integer or null | [Percentage](#percentages) consumed, integer 0-100. `null` if [unlimited](#unlimited-allowances) |
| `remainingPercent` | integer or null | [Percentage](#percentages) remaining, integer 0-100. `null` if [unlimited](#unlimited-allowances) |
| `usableFrom` | datetime or null | Start of the window this balance covers. `null` for pending add-ons not yet activated |
| `usableUntil` | datetime or null | End of the window this balance covers. `null` for pending add-ons not yet activated |

## Allowance

An Allowance defines what a product (plan or add-on) entitles a user to. It is a definition: it describes what is included but does not track consumption.

| Field | Type | Description |
|---|---|---|
| `object` | string | Always `"allowance"` |
| `id` | string | Unique identifier (prefixed `alw_`) - see [ID Prefixes](#id-prefixes) |
| `name` | string | Human-readable label from the plan or add-on, e.g. "Roaming data in Europe" |
| `type` | string | One of `data`, `voice`, or `sms` - see [Units](#units) |
| `coverage` | object | Geographic scope (see [Coverage](#coverage)) |
| `limit` | integer or null | Maximum amount of `unit` available to this Allowance. `null` means [unlimited](#unlimited-allowances) |
| `unit` | string | One of `bytes`, `seconds`, or `messages` - see [Units](#units) |

Note a single plan or add-on can have multiple Allowances. For example: 20 GB roaming data, 3000 seconds of international voice and 100 international SMS, each a separate Allowance - see [How Balances Map to Allowances](#how-balances-map-to-allowances).

### Unlimited allowances

If the product is an unlimited plan, unlimited allowances return `limit` as `null`.

- When `limit` is `null`, `remaining`, `usedPercent`, and `remainingPercent` are all also `null`.
- The `used` field still increments.
- Check `limit` for `null` before doing arithmetic or rendering progress bars.

<CodeGroup title="Example of an unlimited balance fields">

```json
{
  "used": 52000000000,
  "limit": null,
  "remaining": null,
  "usedPercent": null,
  "remainingPercent": null
}
```

</CodeGroup>

### Coverage

A Coverage object describes the geographic scope of an [Allowance](#allowance).

| Field | Type | Description |
|---|---|---|
| `object` | string | Always `"coverage"` |
| `id` | string | Short identifier, e.g. `"global"`, `"eu"` |
| `name` | string | Human-readable name, e.g. `"Europe"` |
| `countries` | array of strings | ISO 3166 country codes where the allowance applies |

Coverage helps determine which usage counts against which Allowance. Data used in France counts against an Allowance whose coverage includes `"FR"`.

When multiple Allowances overlap geographically (e.g. "Europe" and "Global" both cover France), the carrier determines consumption priority. The Usage Balance API reflects the result but does not expose priority rules directly.

## Source

Every Usage Balance has a `source` indicating where the allowance comes from, which contains the follow fields...

| Field | Type | Meaning |
|---|---|---|
| `type` | `string` | Either `subscriptionPeriod` or `subscriptionAddon` |
| `subscriptionPeriod` | `integer` | The number of the subscription [period](#subscription-period). |
| `subscriptionAddon` | `string` | The ID of the add-on e.g. `sad_0VEIgoYA3lDwMx1CEihKTo9joStp` - see [ID Prefixes](#id-prefixes) |

<Note type="warning">

Although three fields are defined for Source, only two will ever be returned by the API - the `type` field and either the `subscriptionPeriod` or the `subscriptionAddon`. A period-sourced balance has `subscriptionPeriod` but no `subscriptionAddon` field, and vice versa - see [How Balances Map to Allowances](#how-balances-map-to-allowances). Be careful not define types that assume both fields exist.

OpenAPI schema examples may show both fields with the irrelevant one set to null, but the API response only includes the field matching source.type.

</Note>

### Subscription period

A subscription period is a billing cycle numbered sequentially starting from 1. Period 1 is the first billing cycle after activation, period 2 is the next, and so on. Each period has a start and end time determined by the plan's billing interval (e.g. monthly).

Period-sourced Usage Balances renew each period. When a new period starts, fresh Usage Balances are created with reset limits for that period's allowances.

**Note** subscription periods only apply to plans and not add-ons.

### Period-sourced example:

<CodeGroup title="Period-sourced source object">

```json
{
  "type": "subscriptionPeriod",
  "subscriptionPeriod": 1
}
```

</CodeGroup>

### Add-on-sourced example:

<CodeGroup title="Add-on-sourced source object">

```json
{
  "type": "subscriptionAddon",
  "subscriptionAddon": "sad_0VEIgoYA3lDwMx1CEihKTo9joStp"
}
```

</CodeGroup>

## Units

The `unit` the usage is counted in. Allowed values:

| Unit | Usage type | Conversion |
|---|---|---|
| `bytes` | Data | / 1,000,000,000 for GB, / 1,000,000 for MB |
| `seconds` | Voice Calls | / 60 for minutes, / 3600 for hours |
| `messages` | SMS | No conversion needed |

<Note type="info">

The [Add-on API][addons-guide] uses compound field names for allowances (`dataBytes`, `voiceSeconds`, `smsMessages`). The Usage Balance API uses separate `type` and `unit` fields instead.

The mapping:
- `dataBytes` = type `data` / unit `bytes`
- `voiceSeconds` = type `voice` / unit `seconds`
- `smsMessages` = type `sms` / unit `messages`.

</Note>

### Percentages

Percentages are all integers so `usedPercent` and `remainingPercent` will be between 0 and 100. A user at 46% usage will have `"usedPercent": 46`, not `46.0`.

## ID prefixes

| Prefix | Entity |
|---|---|
| `ubl_` | Usage Balance ID |
| `alw_` | Allowance ID |
| `sub_` | [Subscription ID][subscription-id] |
| `sad_` | [Subscription add-on ID][addon-id] |

## Next steps

- [Usage APIs][usage-apis] - How to use the Usage Balance API and the Usage API
- [Usage Events][usage-events] -  Subscribe to webhook events for usage thresholds, first-use detection, and data throttling on Gigs subscriptions.
- [Testing Usage Balances][usage-balances-testing] - How to test and simulate usage on Usage Balances.

[usage-apis]: /docs/core/usage/apis-for-usage
[usage-balances-api]: /api/latest/core/usage-balances
[usage-records-core-concepts]: /docs/core/usage/usage-records-core-concepts
[addons-guide]: /docs/core/add-ons
[usage-balances-testing]: /docs/core/usage/testing-usage-balances
[usage-events]: /docs/core/usage/usage-events
[subscription]: /docs/create-a-subscription
[subscription-id]: /api/latest/core/subscriptions
[addon-id]: /api/latest/core/subscription-add-ons