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

# POST /api/v1/usage-events — Record a Metered Usage Event

> POST /api/v1/usage-events — records a metered usage event for a subscription. Used for billing API calls, tokens, or other quantifiable actions.

Usage events track what a subscriber consumes under a subscription so Retempo can aggregate metered billing accurately. Each event records a discrete action — an API call, a generated token, a processed document — identified by an `eventKey` and a `quantity`. You can attach usage events to an open invoice for precise per-period billing, or leave `invoiceId` unset and reconcile later.

```
POST https://api.retempo.xyz/api/v1/usage-events
```

## Request Body

<ParamField body="serviceId" type="string" required>
  The ID of the service the usage occurred on.
</ParamField>

<ParamField body="subscriptionId" type="string" required>
  The ID of the subscription this usage belongs to. Must belong to the specified `serviceId` and `userId`.
</ParamField>

<ParamField body="userId" type="string" required>
  The ID of the subscriber who generated the usage.
</ParamField>

<ParamField body="eventKey" type="string" required>
  A string identifier for the type of usage being recorded (e.g. `api_request`, `token_generated`). The combination of `subscriptionId` + `eventKey` must be unique — submitting the same pair twice returns a `409`.
</ParamField>

<ParamField body="quantity" type="string | number" required>
  The amount consumed. Pass as a decimal string (e.g. `"1000.000000"`) or a number. Must be a non-negative value.
</ParamField>

<ParamField body="invoiceId" type="string">
  The ID of an invoice to associate with this usage event. If provided, the invoice must belong to the same `serviceId` and `userId`. Optional — omit to reconcile usage to an invoice later.
</ParamField>

<ParamField body="occurredAt" type="string">
  An ISO 8601 datetime string for when the usage occurred. Defaults to the time of the API call if omitted. Pass this to backfill historical usage.
</ParamField>

## Response

A successful request returns HTTP `201 Created` with the new usage event object and all related records.

<ResponseField name="usageEvent" type="object">
  The newly recorded usage event with related records.

  <Expandable title="usageEvent fields">
    <ResponseField name="id" type="string">Unique identifier for the usage event.</ResponseField>
    <ResponseField name="serviceId" type="string">ID of the associated service.</ResponseField>
    <ResponseField name="subscriptionId" type="string">ID of the associated subscription.</ResponseField>
    <ResponseField name="userId" type="string">ID of the subscriber.</ResponseField>
    <ResponseField name="invoiceId" type="string | null">ID of the linked invoice, or `null` if not attached.</ResponseField>
    <ResponseField name="eventKey" type="string">The usage type identifier you provided.</ResponseField>
    <ResponseField name="quantity" type="string">The recorded quantity as a decimal string.</ResponseField>
    <ResponseField name="occurredAt" type="string">ISO 8601 datetime when the usage occurred.</ResponseField>
    <ResponseField name="createdAt" type="string">ISO 8601 datetime the event was recorded.</ResponseField>
    <ResponseField name="invoice" type="object | null">Nested invoice object if `invoiceId` was provided, otherwise `null`.</ResponseField>
    <ResponseField name="service" type="object">Nested service object.</ResponseField>
    <ResponseField name="subscription" type="object">Nested subscription object.</ResponseField>
    <ResponseField name="user" type="object">Nested user object.</ResponseField>
  </Expandable>
</ResponseField>

### 201 — Usage event recorded

```json theme={null}
{
  "usageEvent": {
    "id": "clz1usage333",
    "serviceId": "clz1abc2def3ghi4",
    "subscriptionId": "clz1sub444",
    "userId": "clz1user111",
    "invoiceId": "clz1invoice999",
    "eventKey": "token_generated",
    "quantity": "1000.000000",
    "occurredAt": "2025-06-01T10:25:00.000Z",
    "createdAt": "2025-06-01T10:25:00.000Z",
    "invoice": {
      "id": "clz1invoice999",
      "status": "OPEN",
      "amount": "49.000000",
      "currency": "USDC"
    },
    "service": {
      "id": "clz1abc2def3ghi4",
      "name": "DataStream Pro"
    },
    "subscription": {
      "id": "clz1sub444"
    },
    "user": {
      "id": "clz1user111",
      "email": "subscriber@example.com"
    }
  }
}
```

## Example Request

```bash theme={null}
curl -X POST https://api.retempo.xyz/api/v1/usage-events \
  -H "Content-Type: application/json" \
  -d '{
    "serviceId": "clz1abc2def3ghi4",
    "subscriptionId": "clz1sub444",
    "userId": "clz1user111",
    "eventKey": "token_generated",
    "quantity": "1000.000000",
    "invoiceId": "clz1invoice999",
    "occurredAt": "2025-06-01T10:25:00.000Z"
  }'
```

## Error Codes

| Status            | Message                                                      | Condition                                                                             |
| ----------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------- |
| `400 Bad Request` | `serviceId is required.`                                     | `serviceId` was omitted.                                                              |
| `400 Bad Request` | `subscriptionId is required.`                                | `subscriptionId` was omitted.                                                         |
| `400 Bad Request` | `userId is required.`                                        | `userId` was omitted.                                                                 |
| `400 Bad Request` | `eventKey is required.`                                      | `eventKey` was omitted.                                                               |
| `400 Bad Request` | `quantity is required.`                                      | `quantity` was omitted.                                                               |
| `400 Bad Request` | `Invoice does not match the usage event service and user.`   | The provided `invoiceId` belongs to a different service or user.                      |
| `404 Not Found`   | `Subscription was not found for the service and user.`       | The subscription does not exist or does not belong to the specified service and user. |
| `409 Conflict`    | `A database record with these unique fields already exists.` | The `subscriptionId` + `eventKey` combination has already been recorded.              |

<Note>
  The combination of `subscriptionId` + `eventKey` must be unique. Use different `eventKey` values to track different action types within the same subscription. Duplicate submissions return a `409` error.
</Note>

<Tip>
  Pass `occurredAt` in ISO 8601 format to backfill usage events that occurred before the API call. This lets you report usage accurately even when your system processes events asynchronously or in batches.
</Tip>
