# List daily usage

> The usage.aggregates.list operation: GET /api/v1/usage_aggregates in the REST API and the usage_aggregates_list tool in the MCP server.

Lists the brand's daily usage aggregates in the mode of the request: one per customer, meter, day and
attribute set, with the day's sum (`quantity`), event count, largest quantity (`max`) and last event
(`last`). Days are calendar days in the entity's time zone; `start` and `end` are the instants each spans.
Late usage counts on the day it happened.

- `customerId`, `meter`: one customer's or one meter's usage;
- `from`, `to`: the first and last day, inclusive (YYYY-MM-DD).

Newest day first. Paginate with `limit` (1–100, default 10) and `starting_after` (the `next_cursor` of the
previous page).

## At a glance

- **REST:** `GET /api/v1/usage_aggregates`
- **MCP tool:** `usage_aggregates_list`
- **Operation ID:** `usage.aggregates.list`
- **Scope:** Brand
- **Permission:** `usage:read`
- **Risk tier:** `read`
- **Dry run:** Not supported
- **Idempotency:** Not needed (read only)
- **Modes:** Test and live
- **Pagination:** `limit` (at most 100) and `starting_after`
- **Authentication:** API key with the `usage:read` scope
- **Since:** M5

## Request

### Query parameters

| Field            | Type               | Required | Description                                                       |
| ---------------- | ------------------ | -------- | ----------------------------------------------------------------- |
| `limit`          | integer (1 to 100) | No       |                                                                   |
| `starting_after` | `uagg_…` ID        | No       |                                                                   |
| `customerId`     | `cus_…` ID         | No       | Only this customer's usage.                                       |
| `meter`          | string             | No       | Only this meter's usage.                                          |
| `from`           | string             | No       | The first day, inclusive (YYYY-MM-DD, in the entity's time zone). |
| `to`             | string             | No       | The last day, inclusive.                                          |

## Response

`200 OK` with a JSON object, a page of the list (newest first):

| Field               | Type                   | Description                                                                                                                     |
| ------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `object`            | `"list"`               |                                                                                                                                 |
| `data`              | array of object        |                                                                                                                                 |
| `data[].id`         | `uagg_…` ID            |                                                                                                                                 |
| `data[].object`     | `"usage_aggregate"`    |                                                                                                                                 |
| `data[].brandId`    | `brd_…` ID             |                                                                                                                                 |
| `data[].livemode`   | boolean                |                                                                                                                                 |
| `data[].customerId` | `cus_…` ID             |                                                                                                                                 |
| `data[].meter`      | string                 |                                                                                                                                 |
| `data[].period`     | string                 | The calendar day (YYYY-MM-DD) in the entity's time zone.                                                                        |
| `data[].timeZone`   | string                 |                                                                                                                                 |
| `data[].start`      | date-time              | The first instant of the day.                                                                                                   |
| `data[].end`        | date-time              | The first instant of the next day.                                                                                              |
| `data[].attributes` | object                 | The attribute set this aggregate counts ({} for none).                                                                          |
| `data[].quantity`   | integer string         | The sum of the day's quantities (the `sum` aggregation).                                                                        |
| `data[].eventCount` | integer                |                                                                                                                                 |
| `data[].max`        | integer string or null | The largest quantity of the day (the `max` aggregation).                                                                        |
| `data[].last`       | object or null         | The day's last event (the `last` aggregation): by `occurredAt`, then event ID.                                                  |
| `data[].amounts`    | array of money         | Prepaid usage: what the day's events cost, one entry per wallet currency (by currency code). Empty for usage billed in arrears. |
| `data[].updatedAt`  | date-time              |                                                                                                                                 |
| `has_more`          | boolean                |                                                                                                                                 |
| `next_cursor`       | `uagg_…` ID or null    |                                                                                                                                 |

## Examples

### A customer's API calls in October

```http
GET /api/v1/usage_aggregates?customerId=cus_01m4ty3c2b5qx7mhd9k8w6s0a1&meter=api.calls&from=2026-10-01&to=2026-10-31&limit=2
Authorization: Bearer or_test_…
```

Response (`200`):

```json
{
  "object": "list",
  "data": [
    {
      "id": "uagg_01m4v0d9k2j7r5t3w8x6y4z2a2",
      "object": "usage_aggregate",
      "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
      "livemode": false,
      "customerId": "cus_01m4ty3c2b5qx7mhd9k8w6s0a1",
      "meter": "api.calls",
      "period": "2026-10-13",
      "timeZone": "Europe/Zagreb",
      "start": "2026-10-12T22:00:00.000Z",
      "end": "2026-10-13T22:00:00.000Z",
      "attributes": {
        "model": "large"
      },
      "quantity": "4230",
      "eventCount": 37,
      "max": "640",
      "last": {
        "quantity": "120",
        "occurredAt": "2026-10-13T21:40:00.000Z",
        "eventId": "uev_01m4v0d9k2j7r5t3w8x6y4z2a1"
      },
      "amounts": [],
      "updatedAt": "2026-10-13T21:40:01.000Z"
    },
    {
      "id": "uagg_01m4v0d9k2j7r5t3w8x6y4z2a3",
      "object": "usage_aggregate",
      "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
      "livemode": false,
      "customerId": "cus_01m4ty3c2b5qx7mhd9k8w6s0a1",
      "meter": "api.calls",
      "period": "2026-10-12",
      "timeZone": "Europe/Zagreb",
      "start": "2026-10-11T22:00:00.000Z",
      "end": "2026-10-12T22:00:00.000Z",
      "attributes": {
        "model": "large"
      },
      "quantity": "3910",
      "eventCount": 31,
      "max": "512",
      "last": {
        "quantity": "64",
        "occurredAt": "2026-10-12T20:05:00.000Z",
        "eventId": "uev_01m4v0d9k2j7r5t3w8x6y4z2a0"
      },
      "amounts": [],
      "updatedAt": "2026-10-12T20:05:01.000Z"
    }
  ],
  "has_more": true,
  "next_cursor": "uagg_01m4v0d9k2j7r5t3w8x6y4z2a3"
}
```

## Errors

| Code                                                                                   | HTTP status | When                                                | What to do                                                                      |
| -------------------------------------------------------------------------------------- | ----------- | --------------------------------------------------- | ------------------------------------------------------------------------------- |
| [`validation_failed`](https://ownrecord.io/docs/reference/errors.md#validation_failed) | 400         | A filter, the page size or the cursor is malformed. | Fix the fields listed in `details.issues` and send the request again.           |
| [`permission_denied`](https://ownrecord.io/docs/reference/errors.md#permission_denied) | 403         | You can't read this brand's usage (`usage:read`).   | Ask an organization owner or admin for a role or scope that allows this action. |

It can also return these [common errors](https://ownrecord.io/docs/reference.md#common-errors): [`api_version_unsupported`](https://ownrecord.io/docs/reference/errors.md#api_version_unsupported), [`authentication_required`](https://ownrecord.io/docs/reference/errors.md#authentication_required), [`api_key_invalid`](https://ownrecord.io/docs/reference/errors.md#api_key_invalid), [`scope_required`](https://ownrecord.io/docs/reference/errors.md#scope_required), [`resource_not_found`](https://ownrecord.io/docs/reference/errors.md#resource_not_found), [`dry_run_not_supported`](https://ownrecord.io/docs/reference/errors.md#dry_run_not_supported), [`rate_limited`](https://ownrecord.io/docs/reference/errors.md#rate_limited), [`internal_error`](https://ownrecord.io/docs/reference/errors.md#internal_error).
