> ## Documentation Index
> Fetch the complete documentation index at: https://dev.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.

<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>


## OpenAPI

````yaml get /usage/v1/records
openapi: 3.0.0
info:
  title: Inworld Usage API
  version: v1
  contact:
    name: Inworld AI
    url: https://inworld.ai
    email: support@inworld.ai
servers:
  - url: https://api.inworld.ai
security:
  - inworld_basic: []
tags:
  - name: Usage
paths:
  /usage/v1/records:
    get:
      tags:
        - Usage
      summary: Query usage records
      description: >-
        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.
      operationId: UsageService_QueryUsageRecords2
      parameters:
        - name: startTime
          description: Range start, inclusive.
          in: query
          required: true
          schema:
            type: string
            format: date-time
        - name: endTime
          description: Range end, exclusive.
          in: query
          required: true
          schema:
            type: string
            format: date-time
        - name: granularity
          description: |-
            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.
          in: query
          required: false
          schema:
            type: string
            enum:
              - GRANULARITY_UNSPECIFIED
              - GRANULARITY_HOUR
              - GRANULARITY_DAY
              - GRANULARITY_MONTH
            default: GRANULARITY_DAY
        - name: timeZone
          description: >-
            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`.
          in: query
          required: false
          schema:
            type: string
        - name: groupBy
          description: >-
            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.
          in: query
          required: false
          explode: true
          schema:
            type: array
            items:
              type: string
              enum:
                - USAGE_DIMENSION_UNSPECIFIED
                - USAGE_DIMENSION_SERVICE
                - USAGE_DIMENSION_MODEL
                - USAGE_DIMENSION_SERVICE_PROVIDER
                - USAGE_DIMENSION_API_KEY
        - name: services
          description: |-
            Service filter (e.g. "tts"). Open strings; repeated values mean IN
            semantics — same for the other dimension filters below.
          in: query
          required: false
          explode: true
          schema:
            type: array
            items:
              type: string
        - name: models
          description: Model filter (e.g. "tts-2.0").
          in: query
          required: false
          explode: true
          schema:
            type: array
            items:
              type: string
        - name: serviceProviders
          description: Service-provider filter.
          in: query
          required: false
          explode: true
          schema:
            type: array
            items:
              type: string
        - name: apiKeyIds
          description: >-
            Same-workspace API-key filter. Rejected when the backing store
            cannot

            apply it faithfully (never silently ignored).
          in: query
          required: false
          explode: true
          schema:
            type: array
            items:
              type: string
        - name: metrics
          description: >-
            Metric selection (e.g. "characters", "`input_tokens`"). Empty means
            all

            consumption metrics for the requested services; never plan fees.
          in: query
          required: false
          explode: true
          schema:
            type: array
            items:
              type: string
        - name: pageSize
          description: >-
            Maximum records per page; values above the server maximum are
            coerced.
          in: query
          required: false
          schema:
            type: integer
            format: int32
        - name: pageToken
          description: Opaque cursor from a previous response.
          in: query
          required: false
          schema:
            type: string
      responses:
        '200':
          description: A successful response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/v1QueryUsageRecordsResponse'
              example:
                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:
          description: An unexpected error response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/rpcStatus'
components:
  schemas:
    v1QueryUsageRecordsResponse:
      type: object
      properties:
        usageRecords:
          type: array
          items:
            $ref: '#/components/schemas/v1UsageRecord'
          description: >-
            Usage rows for the requested range: one per time bucket × dimension
            group.
        nextPageToken:
          type: string
          description: Empty when there are no further pages.
        totalSize:
          type: integer
          format: int32
          description: >-
            Omitted by default (expensive to compute per page); explicit
            presence so

            clients can tell "absent" from a real 0.
          readOnly: true
        readTime:
          type: string
          format: date-time
          description: |-
            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.
          readOnly: true
      description: Response for QueryUsageRecords.
    rpcStatus:
      type: object
      properties:
        code:
          type: integer
          format: int32
          description: |-
            The status code, which should be an enum value of
            [google.rpc.Code][google.rpc.Code].
        message:
          type: string
          description: >-
            A developer-facing error message, which should be in English. Any

            user-facing error message should be localized and sent in the

            [google.rpc.Status.details][google.rpc.Status.details] field, or
            localized

            by the client.
        details:
          type: array
          items:
            $ref: '#/components/schemas/protobufAny'
          description: >-
            A list of messages that carry the error details.  There is a common
            set of

            message types for APIs to use.
      description: >-
        The `Status` type defines a logical error model that is suitable for

        different programming environments, including REST APIs and RPC APIs. It
        is

        used by [gRPC](https://github.com/grpc). Each `Status` message contains

        three pieces of data: error code, error message, and error details.


        You can find out more about this error model and how to work with it in
        the

        [API Design Guide](https://cloud.google.com/apis/design/errors).
    v1UsageRecord:
      type: object
      properties:
        startTime:
          type: string
          format: date-time
          description: Bucket start, inclusive.
        endTime:
          type: string
          format: date-time
          description: Bucket end, exclusive.
        group:
          type: object
          additionalProperties:
            type: string
          description: >-
            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:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/v1MetricValue'
          description: Metric name -> value. Adding a metric is one more entry (additive).
      description: One time bucket × one dimension group.
    protobufAny:
      type: object
      properties:
        '@type':
          type: string
          description: >-
            A URL/resource name that uniquely identifies the type of the
            serialized

            protocol buffer message. This string must contain at least

            one "/" character. The last segment of the URL's path must represent

            the fully qualified name of the type (as in

            `path/google.protobuf.Duration`). The name should be in a canonical
            form

            (e.g., leading "." is not accepted).


            In practice, teams usually precompile into the binary all types that
            they

            expect it to use in the context of Any. However, for URLs which use
            the

            scheme `http`, `https`, or no scheme, one can optionally set up a
            type

            server that maps type URLs to message definitions as follows:


            * If no scheme is provided, `https` is assumed.

            * An HTTP GET on the URL must yield a [google.protobuf.Type][]
              value in binary format, or produce an error.
            * Applications are allowed to cache lookup results based on the
              URL, or have them precompiled into a binary to avoid any
              lookup. Therefore, binary compatibility needs to be preserved
              on changes to types. (Use versioned type names to manage
              breaking changes.)

            Note: this functionality is not currently available in the official

            protobuf release, and it is not used for type URLs beginning with

            type.googleapis.com. As of May 2023, there are no widely used type
            server

            implementations and no plans to implement one.


            Schemes other than `http`, `https` (or the empty scheme) might be

            used with implementation specific semantics.
      additionalProperties: {}
      description: >-
        `Any` contains an arbitrary serialized protocol buffer message along
        with a

        URL that describes the type of the serialized message.


        Protobuf library provides support to pack/unpack Any values in the form

        of utility functions or additional generated methods of the Any type.


        Example 1: Pack and unpack a message in C++.

            Foo foo = ...;
            Any any;
            any.PackFrom(foo);
            ...
            if (any.UnpackTo(&foo)) {
              ...
            }

        Example 2: Pack and unpack a message in Java.

            Foo foo = ...;
            Any any = Any.pack(foo);
            ...
            if (any.is(Foo.class)) {
              foo = any.unpack(Foo.class);
            }
            // or ...
            if (any.isSameTypeAs(Foo.getDefaultInstance())) {
              foo = any.unpack(Foo.getDefaultInstance());
            }

         Example 3: Pack and unpack a message in Python.

            foo = Foo(...)
            any = Any()
            any.Pack(foo)
            ...
            if any.Is(Foo.DESCRIPTOR):
              any.Unpack(foo)
              ...

         Example 4: Pack and unpack a message in Go

             foo := &pb.Foo{...}
             any, err := anypb.New(foo)
             if err != nil {
               ...
             }
             ...
             foo := &pb.Foo{}
             if err := any.UnmarshalTo(foo); err != nil {
               ...
             }

        The pack methods provided by protobuf library will by default use

        'type.googleapis.com/full.type.name' as the type URL and the unpack

        methods only use the fully qualified type name after the last '/'

        in the type URL, for example "foo.bar.com/x/y.z" will yield type

        name "y.z".


        JSON

        ====

        The JSON representation of an `Any` value uses the regular

        representation of the deserialized, embedded message, with an

        additional field `@type` which contains the type URL. Example:

            package google.profile;
            message Person {
              string `first_name` = 1;
              string `last_name` = 2;
            }

            {
              "@type": "type.googleapis.com/google.profile.Person",
              "firstName": <string>,
              "lastName": <string>
            }

        If the embedded message type is well-known and has a custom JSON

        representation, that representation will be embedded adding a field

        `value` which holds the custom JSON in addition to the `@type`

        field. Example (for message [google.protobuf.Duration][]):

            {
              "@type": "type.googleapis.com/google.protobuf.Duration",
              "value": "1.212s"
            }
    v1MetricValue:
      type: object
      properties:
        value:
          type: string
          format: int64
          description: Volume in the unit below. Integer base units only.
        unit:
          type: string
          title: '"characters" | "tokens" | "seconds"'
      description: >-
        A metric value with its unit, so mixed units (characters / tokens /

        seconds) can coexist in one response and new metrics stay
        self-describing.
  securitySchemes:
    inworld_basic:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Your [authentication](../../../api-reference/introduction) credentials.
        For Basic authentication, please populate `Basic $INWORLD_API_KEY`.

````