> ## Documentation Index
> Fetch the complete documentation index at: https://docs.inworld.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Query usage records

> Returns metered usage volume (characters, tokens, seconds) for the workspace that owns the API key, aggregated into UTC time buckets. Volume only — not invoiced amounts. Data is complete up to `readTime` (roughly one hour behind real time); re-fetch recent windows rather than treating them as final. History depth: the last 30 days. `int64` values are returned as JSON strings.

<Warning>
This is an **Experimental** release: the API is subject to change, and historical numbers may be adjusted in rare cases.
</Warning>

<Note>The Usage API is available on the **Builder** plan and above.</Note>

<Note>
Usage data is aggregated into whole UTC buckets (days by default, hours for ranges up to 30 days) and reflects metered volume — characters, tokens and audio seconds — not invoiced amounts. Data is complete up to `readTime`, roughly one hour behind real time: re-fetch recent windows rather than treating them as final. History is available for the last 30 days. `int64` metric values are returned as JSON strings.
</Note>

## API reference

**Endpoint:** `GET https://api.inworld.ai/usage/v1/records`

### Authorization

- `Authorization` (string; required) — Your [authentication](../../../api-reference/introduction) credentials. For Basic authentication, please populate `Basic $INWORLD_API_KEY`.

### Query parameters

- `startTime` (string; required) — Range start, inclusive.
- `endTime` (string; required) — Range end, exclusive.
- `granularity` (enum<string>; default: "GRANULARITY_DAY"; options: "GRANULARITY_UNSPECIFIED", "GRANULARITY_HOUR", "GRANULARITY_DAY", "GRANULARITY_MONTH") — Bucket size; defaults to `GRANULARITY_DAY`.
  
   - `GRANULARITY_UNSPECIFIED`: Unspecified; treated as `GRANULARITY_DAY`.
   - `GRANULARITY_HOUR`: Calendar hour in UTC. Supported for ranges up to 30 days; longer ranges
  are rejected with `INVALID_ARGUMENT`.
   - `GRANULARITY_DAY`: Default. Calendar day in UTC.
   - `GRANULARITY_MONTH`: Reserved; not offered in v1.
- `timeZone` (string) — IANA time zone for bucket boundaries. Not supported in v1 — buckets are
  always computed in UTC. Clients must leave this unset; servers reject
  non-empty values with `INVALID_ARGUMENT`.
- `groupBy` (enum<string>[]) — Dimensions to group by. Omitted: one row per time bucket, all models
  summed. `USAGE_DIMENSION_API_KEY` is filter-only in v1 — servers reject it
  here with `INVALID_ARGUMENT`.
  
   - `USAGE_DIMENSION_UNSPECIFIED`: Unspecified; invalid as a `group_by` value.
   - `USAGE_DIMENSION_SERVICE`: tts | llm | stt | ...
   - `USAGE_DIMENSION_MODEL`: e.g. tts-2.0. The v1 main path.
   - `USAGE_DIMENSION_SERVICE_PROVIDER`: Upstream inference provider.
   - `USAGE_DIMENSION_API_KEY`: Filter only in v1; `group_by` support later.
- `services` (string[]) — Service filter (e.g. "tts"). Open strings; repeated values mean IN
  semantics — same for the other dimension filters below.
- `models` (string[]) — Model filter (e.g. "tts-2.0").
- `serviceProviders` (string[]) — Service-provider filter.
- `apiKeyIds` (string[]) — Same-workspace API-key filter. Rejected when the backing store cannot
  apply it faithfully (never silently ignored).
- `metrics` (string[]) — Metric selection (e.g. "characters", "`input_tokens`"). Empty means all
  consumption metrics for the requested services; never plan fees.
- `pageSize` (integer) — Maximum records per page; values above the server maximum are coerced.
- `pageToken` (string) — Opaque cursor from a previous response.

### Response

Status: `200`. Content type: `application/json`.

- `usageRecords` (object[]) — Usage rows for the requested range: one per time bucket × dimension group.
  - `startTime` (string) — Bucket start, inclusive.
  - `endTime` (string) — Bucket end, exclusive.
  - `group` (object) — Dimension key -> value for this row; present keys mirror the requested
    `group_by` set. Keys are stable `lower_snake_case` names matching
    UsageDimension: "service", "model", "`service_provider`" (later
    "`api_key_id`"). Example: "model": "tts-2.0".
  - `metrics` (object) — Metric name -> value. Adding a metric is one more entry (additive).
- `nextPageToken` (string) — Empty when there are no further pages.
- `totalSize` (integer) — Omitted by default (expensive to compute per page); explicit presence so
  clients can tell "absent" from a real 0.
- `readTime` (string) — Freshness watermark: the returned data is complete up to this time.
  Usage is not a live counter; clients should re-fetch recent windows
  rather than assume immutability.

### Response examples

#### 200: default_response

```json
{
  "usageRecords": [
    {
      "startTime": "2026-08-21T00:00:00Z",
      "endTime": "2026-08-22T00:00:00Z",
      "group": {
        "model": "inworld-tts-2",
        "service": "tts"
      },
      "metrics": {
        "characters": {
          "value": "17250",
          "unit": "characters"
        }
      }
    },
    {
      "startTime": "2026-08-21T00:00:00Z",
      "endTime": "2026-08-22T00:00:00Z",
      "group": {
        "model": "gpt-4o-mini",
        "service": "llm"
      },
      "metrics": {
        "input_tokens": {
          "value": "21930",
          "unit": "tokens"
        },
        "output_tokens": {
          "value": "181",
          "unit": "tokens"
        },
        "cached_read_tokens": {
          "value": "3168",
          "unit": "tokens"
        }
      }
    }
  ],
  "nextPageToken": "",
  "readTime": "2026-08-28T17:31:51Z"
}
```

#### default: default_response

```json
{
  "code": 0,
  "message": "string",
  "details": [
    {
      "@type": "string"
    }
  ]
}
```

### Code examples

#### cURL

```curl
curl --request GET \
  --url https://api.inworld.ai/usage/v1/records \
  --header 'Authorization: <api_key>'
```

#### Python

```python
import requests

url = "https://api.inworld.ai/usage/v1/records"
headers = {
  "Authorization": "<api_key>"
}

response = requests.request("GET", url, headers=headers)

print(response.text)
```

#### JavaScript

```javascript
const options = {method: 'GET', headers: {"Authorization":"<api_key>"}};

fetch('https://api.inworld.ai/usage/v1/records', options)
  .then(response => response.json())
  .then(response => console.log(response))
  .catch(err => console.error(err));
```
