# Usage

Metered usage is ingested by your systems (or Fynex connectors), aggregated
per contract, metric, and billing period, and rated into usage invoices at
period close. This API exposes the aggregated view.

## Endpoints

- `GET /billing-api/v1/contracts` — the contracts visible to your key, the
  entry point for every per-contract read. Paged by ascending contract id:
  while `hasMore` is true, pass the returned `nextCursor` back as `cursor`.

```json
{
  "contracts": [
    {
      "contractId": 42,
      "contractNumber": "UK2607AA",
      "version": 1,
      "sellerCustomerId": 7,
      "currency": "EUR",
      "status": "active",
      "startDate": "2026-01-01",
      "customerName": "Ada Lovelace",
      "customerCompanyName": "Harbour Group BV"
    }
  ],
  "hasMore": false
}
```

- `GET /billing-api/v1/contracts/{contractId}/usage` — the current open
  billing periods of every metric on the contract:

```json
{
  "contractId": 42,
  "metrics": [
    {
      "metricName": "api_calls",
      "used": "10250",
      "includedUnits": "10000",
      "capQuantity": "50000",
      "capMode": "hard",
      "percentOfCap": "20.5",
      "percentOfPlan": "102.5",
      "periodStart": "2026-08-01",
      "periodEnd": "2026-08-31"
    }
  ]
}
```

`used` counts everything metered this period; `includedUnits` is the plan
allowance; `capQuantity`/`capMode` describe the limit policy when one is
configured. Quantities are decimal strings. An unknown contract id answers
`404`; a real contract with nothing metered answers `200` with an empty
`metrics` array.

> [!IMPORTANT]
> **This is a live reading, not the figure the customer will be invoiced.**
> The period is still open, so `used` moves with every event that arrives —
> including events for work already done that reach us late. It is also
> pre-invoice: allowances, credits, discounts and rounding are applied when the
> period closes and the invoice is produced, and none of them are reflected
> here.
>
> Show it to a customer as "usage so far", never as an amount owed, and
> reconcile against the invoice the period produced rather than against this
> endpoint. A dashboard that quotes this number as the bill will disagree with
> the bill.

This endpoint reads a meter; something has to fill it. Writing usage —
registering a metric, pricing it, and sending events — happens under
`/billing-api/v1/usage`, with the same seller secret key, and is documented in
full under **Usage ingestion**. In short: `POST /billing-api/v1/usage/metrics`
to declare the meter, `PUT
/billing-api/v1/usage/contracts/{contractId}/metrics/{metricName}/price` to
price it, and `POST /billing-api/v1/usage/events` (or `:batch`, or `/csv`) to
report consumption.

## What this endpoint keeps, and for how long

**This is a meter, not a history API.** It answers with the contract's
**currently open** billing periods — one entry per metric with a limit policy
or metered usage. It has no date range and no paging, and a period that has
closed is no longer in the response. If you need consumption over time, record
what you read while the period is open, or take it from the invoice the period
produced: the invoice is the durable record of what was billed.

**Stored events are retained indefinitely.** Nothing prunes them — there is no
retention window on ingested usage and no job that deletes it, so an
idempotency key you used a year ago is still recognised and resending that
event is still a no-op. Two practical consequences:

- Idempotency keys must stay unique for the lifetime of your integration, not
  just for a period. Derive them from something durable — a row id, an export
  digest — rather than from a timestamp that repeats.
- Correcting metered history is done by issuing a correction against the period
  (see **Usage corrections**), never by deleting events. There is no delete.

Documents are the exception: invoices and credit notes carry a statutory
retention period per jurisdiction, which is a legal minimum on how long they
are kept, not a window after which this endpoint stops answering.
