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

# Report Usage Event

> Reports one usage event (value, occurred_at) for an active subscription against a meter, idempotent on event_id.

<Note>
  **Enabled per organization**

  Usage-based billing must be enabled for your organization before these endpoints accept requests. Contact your Yuno account manager to enable it. Requests from an organization where it is not enabled return `403 PRODUCT_NOT_ENABLED`.
</Note>

Send one event per request, with a unique `X-Idempotency-Key` header. Yuno resolves the meter from `event_name`, validates the event synchronously and stores it against the `subscription_id`. `ACTIVE`, `TRIALING` and `PAST_DUE` subscriptions accept usage — `PAUSED`, `CANCELED` and `COMPLETED` are rejected with `400 SUBSCRIPTION_NOT_ACTIVE` and nothing is counted. Usage is aggregated per subscription and billing cycle according to the meter's `aggregation`, and any usage beyond the included `credits` is billed on the subscription's renewal charge.

<Note>
  **`event_id` is your idempotency key**

  Generate a unique `event_id` for every event (a UUID or your own event/request id) and reuse it on retries. A replay returns the same response as the first call — including the original `value`, even if the retry carried a different one (the retry's value is discarded) — and the usage is never counted twice. `event_id` is unique per account and required: a request without it is rejected with `400`. This is the mechanism that protects billing; `X-Idempotency-Key` is accepted (optional, as on the rest of the Yuno API) but is not required and is not what dedupes usage.
</Note>

<Note>
  **Timestamps**

  `occurred_at` defaults to the time Yuno receives the event (returned as `received_at`). You can backdate up to 35 days; older values are rejected with `400`. Which billing cycle an event lands in is decided by `occurred_at`, not by when it was received.
</Note>

<Note>
  An unknown `event_name` (or an archived meter) is a `400 METER_NOT_FOUND`; an unknown `subscription_id` is a `400 SUBSCRIPTION_NOT_FOUND`. The event carries no `country` or `account_id` — both are resolved from the subscription.
</Note>

Refer to [Meter Error Codes](/reference/meters/meter-error-codes) for the possible error outcomes.


## OpenAPI

````yaml openapi/meters/report-usage-event.json POST /subscriptions/meters/events
openapi: 3.1.0
info:
  title: meters
  version: 1.0.0
servers:
  - url: https://api-sandbox.y.uno/v1
  - url: https://api.eu.y.uno/v1
security:
  - sec0: []
    sec1: []
paths:
  /subscriptions/meters/events:
    post:
      summary: Report Usage Event
      description: >-
        Usage-based billing must be enabled for your organization before this
        endpoint accepts requests (otherwise `403 PRODUCT_NOT_ENABLED`). Reports
        one usage event against a subscription. The meter is resolved from
        `event_name`. Validation is synchronous: a malformed or unresolvable
        event is rejected with `400` and never counted. Replaying the same
        `event_id` returns the original response — including the original
        `value`, even if the retry sent a different one — and never double
        counts. `ACTIVE`, `TRIALING` and `PAST_DUE` subscriptions accept usage;
        any other status is rejected with `400 SUBSCRIPTION_NOT_ACTIVE`. One
        event per request.
      operationId: report-usage-event
      parameters:
        - in: header
          name: X-Account-Code
          required: true
          schema:
            type: string
          description: >-
            The `account_id` found in your [Yuno
            Dashboard](https://dashboard.y.uno/developers) (UUID). Required —
            omitting it returns `400 BAD_REQUEST` ("Invalid x-account-code
            header.").
        - in: header
          name: X-Idempotency-Key
          required: true
          schema:
            type: string
          description: >-
            Unique identifier used in HTTP headers to ensure that a request is
            processed only once, even if it is retried due to network issues or
            timeouts. Optional, as on the rest of the Yuno API.
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - event_id
                - event_name
                - subscription_id
              properties:
                event_id:
                  type: string
                  description: >-
                    Your unique identifier for this event — the idempotency key.
                    Unique per account. Re-sending the same `event_id` returns
                    the same response (including the original `value`) and never
                    counts the usage twice, regardless of retries.
                event_name:
                  type: string
                  description: >-
                    The `event_name` of the meter this event belongs to.
                    Resolves the meter within your account; an unknown or
                    `INACTIVE` meter is rejected with `400 METER_NOT_FOUND`.
                subscription_id:
                  type: string
                  description: >-
                    The unique identifier of the subscription the usage is
                    attributed to (MAX 64; MIN 36). Must exist in your account
                    (`400 SUBSCRIPTION_NOT_FOUND`) and be `ACTIVE`, `TRIALING`
                    or `PAST_DUE` (`400 SUBSCRIPTION_NOT_ACTIVE`). Usage is
                    metered per subscription and billed on that subscription's
                    renewal.
                value:
                  type: number
                  format: float
                  description: >-
                    The quantity to record for this event. Required for `SUM`,
                    `LAST` and `MAX` meters. Must NOT be sent for a `COUNT`
                    meter — an explicit `value` is rejected with `400
                    BAD_REQUEST` ("The value must not be provided for a COUNT
                    meter."); each COUNT event is recorded as `1`.
                occurred_at:
                  type: string
                  description: >-
                    When the usage happened (ISO 8601 with offset). Defaults to
                    the time the event is received. Backdating is accepted up to
                    35 days in the past; older values are rejected with `400
                    INVALID_PARAMETERS`. `occurred_at` decides which billing
                    cycle the event lands in.
                metadata:
                  type: array
                  description: >-
                    Optional key-value pairs stored with the event (MAX 48
                    entries; value MAX 512).
                  items:
                    type: object
                    properties:
                      key:
                        type: string
                      value:
                        type: string
                meter_id:
                  type: string
                  description: >-
                    Optional guard. When sent it must match the meter resolved
                    from `event_name`, otherwise the request is rejected with
                    `400 BAD_REQUEST` ("The meter_id does not match the meter
                    resolved for event_name '<event_name>'.").
            examples:
              Sum meter (tokens):
                summary: SUM meter — tokens consumed
                value:
                  event_id: 11111111-1111-1111-1111-111111111111
                  event_name: ai_tokens
                  subscription_id: 33333333-3333-3333-3333-333333333333
                  value: 1500
                  occurred_at: '2026-08-18T09:00:04Z'
                  metadata:
                    - key: model
                      value: llm-large
              Count meter (API request):
                summary: COUNT meter — value omitted, counts as 1
                value:
                  event_id: req_01J5Y3Q9K8ZC5G6E4Y2W7X8N9M
                  event_name: api_request
                  subscription_id: 33333333-3333-3333-3333-333333333333
              Last meter (storage):
                summary: LAST meter — current gigabytes held
                value:
                  event_id: storage-2026-08-18T09:00-sub-3333
                  event_name: storage_gb
                  subscription_id: 33333333-3333-3333-3333-333333333333
                  value: 128.4
                  occurred_at: '2026-08-18T09:00:00Z'
      responses:
        '201':
          description: '201'
          content:
            application/json:
              examples:
                Result:
                  value:
                    id: 22222222-2222-2222-2222-222222222222
                    event_id: 11111111-1111-1111-1111-111111111111
                    event_name: ai_tokens
                    meter_id: 55555555-5555-5555-5555-555555555555
                    subscription_id: 33333333-3333-3333-3333-333333333333
                    value: 1500
                    received_at: '2026-08-18T09:00:04.000000Z'
              schema:
                type: object
                properties:
                  id:
                    type: string
                    description: Yuno's identifier for the stored event.
                  event_id:
                    type: string
                  event_name:
                    type: string
                  meter_id:
                    type: string
                  subscription_id:
                    type: string
                  value:
                    type: number
                  received_at:
                    type: string
                    description: When Yuno received the event.
        '400':
          description: '400'
          content:
            application/json:
              examples:
                Missing event_id:
                  summary: Missing event_id
                  value:
                    code: INVALID_PARAMETERS
                    messages:
                      - The event_id is required
                Unknown subscription:
                  summary: Unknown subscription
                  value:
                    code: SUBSCRIPTION_NOT_FOUND
                    messages:
                      - >-
                        The subscription does not exist or is not linked to this
                        account.
                Missing value on SUM meter:
                  summary: Missing value on SUM meter
                  value:
                    code: INVALID_PARAMETERS
                    messages:
                      - The value is required for a SUM meter
                Subscription not active:
                  summary: Subscription not active
                  value:
                    code: SUBSCRIPTION_NOT_ACTIVE
                    messages:
                      - The subscription is not active
                occurred_at too old:
                  summary: occurred_at too old
                  value:
                    code: INVALID_PARAMETERS
                    messages:
                      - >-
                        The field 'occurred_at' has an invalid value, it must
                        not be more than 35 days in the past.
                meter_id mismatch:
                  summary: meter_id mismatch
                  value:
                    code: INVALID_PARAMETERS
                    messages:
                      - >-
                        The meter_id does not match the meter resolved from
                        event_name
                Result:
                  value:
                    code: METER_NOT_FOUND
                    messages:
                      - >-
                        No active meter with event_name ai_tokens exists for
                        this account
                  summary: Unknown or inactive meter
              schema:
                type: object
                properties:
                  code:
                    type: string
                  messages:
                    type: array
                    items:
                      type: string
        '403':
          description: '403'
          content:
            application/json:
              examples:
                Product not enabled:
                  summary: Product not enabled
                  value:
                    code: PRODUCT_NOT_ENABLED
                    messages:
                      - Usage-based billing is not enabled for this organization
              schema:
                type: object
                properties:
                  code:
                    type: string
                    example: PRODUCT_NOT_ENABLED
                  messages:
                    type: array
                    items:
                      type: string
      deprecated: false
components:
  securitySchemes:
    sec0:
      type: apiKey
      in: header
      name: public-api-key
      x-default: <Your public-api-key>
    sec1:
      type: apiKey
      in: header
      name: private-secret-key
      x-default: <Your private-secret-key>

````