
# Usage Records Core Concepts

This page covers the data model of the [Usage API][usage-api] (`GET /projects/{project}/subscriptions/{subscription}/usage`). The Usage API returns aggregated consumption records that can be sliced by time range, country, and roaming status, making it suited for reporting and analytics. For showing users how much of their plan or add-on allowance remains, see the [Usage Balances API][usage-balances-api].

## Usage records vs. Usage Balances

The two APIs return different shapes of data for different purposes.

- **Usage record** = an aggregated consumption row for reporting (e.g. "342 MB data on 2024-03-14 in the US")
- **Usage Balance** = an allowance meter for end-user display (e.g. "4.2 GB used of 10 GB on the Europe roaming add-on")

Usage records are time-series rows grouped by an aggregation window. They can be broken down by day, billing period, country, or roaming status, which makes them useful for dashboards, charts, and internal analytics. They report total consumption on a subscription and do not attribute usage to individual allowances or add-ons.

Usage Balances track consumption against specific plan and add-on entitlements, with pre-computed `used`, `remaining`, and percentage fields. They are designed for building user-facing UI like "you have 3.2 GB left."

## The usageRecord object

Each item returned by the Usage API is a `usageRecord`. It contains consumption totals for a single aggregation window along with contextual metadata.

| Field | Type | Description |
|---|---|---|
| `object` | string | Always `"usageRecord"` |
| `data` | integer | Data consumed in bytes |
| `voice` | integer | Voice consumed in seconds |
| `sms` | integer | SMS messages sent and received |
| `start` | datetime | Start of the aggregation window (inclusive) |
| `end` | datetime | End of the aggregation window (exclusive) |
| `labels` | object | Metadata about the record (see [Labels](#labels)) |

### Preview fields

<Note type="info">

The fields below are in Preview and may change without notice. These provide finer-grained breakdowns but are not guaranteed to sum to the base `data`, `voice`, or `sms` fields.

</Note>

| Field | Type | Description |
|---|---|---|
| `dataDeviceBytes` | integer | On-device data in bytes |
| `dataTetheringBytes` | integer | Tethering data in bytes |
| `voiceLocalSeconds` | integer | Local voice calls in seconds |
| `voiceInternationalSeconds` | integer | International voice calls in seconds |
| `smsLocalMessages` | integer | Local SMS count |
| `smsInternationalMessages` | integer | International SMS count |
| `updatedAt` | datetime | Timestamp of the last aggregation update |

### Labels

The `labels` object contains contextual metadata. Which fields are populated depends on the active aggregation dimensions.

| Field | Type | Description |
|---|---|---|
| `labels.country` | string | ISO 3166-1 alpha-2 country code where usage occurred |
| `labels.roaming` | string | Roaming status: `"none"`, `"international"`, or `"domestic"` (Preview) |
| `labels.subscription` | string | Subscription ID (`sub_`) this record belongs to |

## Querying usage records

### Filtering by period

The `period` query parameter limits results to a specific subscription period number. Periods are integers starting at 1, where period 1 is the first billing cycle after activation. This parameter cannot be combined with `start`/`end`.

### Filtering by date range

The `start` and `end` query parameters accept ISO 8601 dates and must be provided together. They define an inclusive start and exclusive end for the query window. These parameters cannot be combined with `period`.

If neither `period` nor `start`/`end` is provided, the API defaults to the latest subscription period.

<Note type="info">

`period` and `start`/`end` are mutually exclusive. The API returns an error if both are provided in the same request.

</Note>

## Aggregation

The `aggregation` query parameter controls how records are grouped. The default is `daily`.

| Value | Grouping |
|---|---|
| `daily` | One record per day (default) |
| `period` | One record per subscription period |
| `country` | One record per country |
| `roaming` | One record per roaming status (Preview) |

You can combine dimensions with a comma. `daily,country` produces one record per day per country. `period,roaming` produces one record per period per roaming status. The `labels` fields present in each record match the aggregation dimensions in the request.

<CodeGroup title="Query usage aggregated by day and country">

```shell
curl --request "GET" \
  --url "https://api.gigs.com/projects/${GIGS_PROJECT}/subscriptions/${SUBSCRIPTION_ID}/usage?aggregation=daily,country" \
  --header "Accept: application/json" \
  --header "Authorization: Bearer ${GIGS_TOKEN}"
```

</CodeGroup>

## Units

All three usage types are returned in every `usageRecord` object.

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

Unlike the Usage Balances API, which has a `unit` field per balance, usage records report all three types in a single object. There is no per-record unit field; `data` is always bytes, `voice` is always seconds, and `sms` is always message count.

## Example response

<CodeGroup title="Full usageRecord response">

```json
{
  "object": "list",
  "items": [
    {
      "object": "usageRecord",
      "data": 18883100,
      "dataDeviceBytes": 30029300,
      "dataTetheringBytes": 30029300,
      "end": "2021-02-15T00:00:00Z",
      "labels": {
        "country": "US",
        "roaming": "none",
        "subscription": "sub_0SNlurA049MEWV2gSfSxi00xlPIi"
      },
      "sms": 15,
      "smsInternationalMessages": 6,
      "smsLocalMessages": 6,
      "start": "2021-02-14T00:00:00Z",
      "updatedAt": "2024-02-15T12:13:14Z",
      "voice": 240,
      "voiceInternationalSeconds": 125,
      "voiceLocalSeconds": 6
    }
  ],
  "moreItemsAfter": null,
  "moreItemsBefore": null
}
```

</CodeGroup>

## Next Steps

- [Usage APIs][usage-apis] - Common API requests for Usage Records and Usage Balances.
- [Usage Balances Core Concepts][usage-balances-core-concepts] - Pre-computed allowance meters for user-facing display.
- [Usage Events][usage-events] - Subscribe to webhook events for usage thresholds and data throttling.

[usage-balances-core-concepts]: /docs/core/usage/usage-balances-core-concepts
[usage-api]: /api/latest/core/usage
[usage-balances-api]: /api/latest/core/usage-balances
[usage-apis]: /docs/core/usage/apis-for-usage
[usage-events]: /docs/core/usage/usage-events