---
title: Realtime Usage Feed
slug: realtime-usage-feed
docTags: 
createdAt: 2026-10-20T00:08:11.630Z
---

A WebSocket push feed of in flight, provisional rated usage and credit burndown. Use it to show consumption, balances, and spend moving in near real time. The feed is read only and carries no derived totals: every value on the wire is read verbatim from the serving store, and any total is your own arithmetic over the delivered fields.

## Endpoint

```text
wss://metering.nue.io/ws
```

**Permission:** metering read access (View Metering Usage, with credit frames gated on View Metering Credits).

## 1. Authenticate

Exchange your session for a short lived feed token, then present it on the WebSocket upgrade.

```text
curl --request POST \
  --url https://metering.nue.io/v1/metering/ws-token \
  --header 'nue-api-key: <your-key>'
```

```json
{ "token": "<jwt>", "expiresIn": 120 }
```

`expiresIn` is seconds. The token carries only the tenant and an expiry. Do not cache it; fetch a fresh one on every connect.

Present it on the upgrade: browser clients via `Sec-WebSocket-Protocol: bearer, <token>`; other clients via `Authorization: Bearer <token>`. The feed validates the token itself and derives the tenant from it. The tenant is never taken from the client.

## 2. Set scope

Scope is set at connect with query parameters. Filters are additive, and a connection that names none receives the whole tenant. To change scope, reconnect.

- `?customer=<customerId>` — a single customer. This is the scope a self service portal uses, so each customer sees only their own usage and burndown across all of their subscriptions.
- `?subscription=<subscriptionNumber>` — a single subscription.

## 3. Receive frames

Each frame carries a `kind`:

- **`snapshot`** — one per connect and reconnect: every in scope open window, plus live pools where available. `windows` is never null; an empty scope ships `[]`. There is no replay of missed messages.
- **`update`** — one changed window in `windows[]`; no pools.
- **`credit`** — one changed pool in `pools[]`.

**Window entry:** `windowKey`, `subscriptionId`, `customerId`, `usageOrderProductId`, `windowStart` / `windowEndTime` (epoch ms), `windowSize`, `windowState`, `cumulativeQuantity`, `meteredQuantity`, `cumulativeQuantityTerm`, `ratedAmount` (decimal strings), `currencyIsoCode`, `ratingTransactionTime` (epoch ms, the version fence).

**Pool entry:** `poolKey`, `customerId`, `creditPoolId`, `liveConsumedCredits`, `liveOverageCredits`, `remaining` (decimal strings), `currencyIsoCode`, `asOf` (epoch ms, the version fence).

```json
{
  "kind": "update",
  "tenantId": "9a7f2e64-3d15-4b82-a6c9-1e5f8b0d47c3",
  "subscriptionId": "SUB-000042",
  "windows": [
    {
      "windowKey": "rtru:window:{tenant:9a7f2e64-…}:01M0V0GKD1…:SUB-000042:model.region\u001fclaude-opus.us-east-1:1789554180000",
      "subscriptionId": "SUB-000042",
      "customerId": "0015g00000ABCDE",
      "windowStart": 1789554180000,
      "windowEndTime": 1789554240000,
      "windowSize": "Minute",
      "windowState": "open",
      "cumulativeQuantity": "18432",
      "meteredQuantity": "18432",
      "ratedAmount": "12.50",
      "currencyIsoCode": "USD",
      "ratingTransactionTime": 1789554204481
    }
  ]
}
```

## Delivery semantics

Delivery is best effort and coalescing. A dropped provisional update self heals on the next tick, and a slow consumer receives the latest state of each scope rather than a backlog. Do not build an at least once assumption on this feed. The figures on the feed are live and provisional; the authoritative amounts are the ones that settle onto the invoice.

## Reconnection

Key reconnect logic off the WebSocket close event, not an HTTP status.

- **Close `1001`** is a deliberate server goodbye (connection lifetime or drain). Mint a new token and reconnect.
- **Close `1006`** is abnormal, and is also what a browser sees on an authentication failure. Mint a new token and retry with backoff. Never hot loop. A readable HTTP `401` exists only for non browser clients.

Open windows update on the rating cadence, typically every few seconds while usage is arriving. A quiet scope produces no frames. Feed connections have a bounded lifetime and drain deliberately.
