Metered usage
A usage component prices a subscription on what the customer used, not on
a fixed quantity. You post events; Paylera aggregates them at period close;
the result becomes the line item on the invoice.
The lifecycle
your service ──► POST /v1/usage ──► aggregator ──► invoice line item- Your application emits a usage event when something happens worth metering (an API call completes, a job runs, a seat is provisioned).
- The event is persisted with
(subscription_id, meter, quantity, timestamp, idempotency_key). - At period close, the aggregator sums events per
(subscription, meter)and feeds the total to the pricing model on the matching component.
Posting an event
POST /v1/usageIdempotency-Key: <uuid>Content-Type: application/json
{ "subscription_id": "sub_…", "meter": "api_calls", "quantity": "1", "timestamp": "2026-05-06T12:34:56Z", "external_id": "req_8f4a…"}external_id is yours — your request ID, your job ID, anything that
deduplicates events within your system. If two events arrive with the same
(subscription_id, meter, external_id), the second is dropped silently
and the response is the same as the first. This is your safety net for
retries.
Quantities are decimals
quantity is a decimal string. You can send fractional units
("0.001") for things measured in milli-anything. Negative quantities are
allowed (-1) for emitting corrections — useful if you over-counted.
Meters
A meter is an arbitrary string you and Paylera agree on. The
meter value on a usage component must match the meter on the events
you post.
By convention, lower-snake-case: api_calls, compute_seconds,
bytes_egress, model_tokens.
Aggregations
Each usage component declares an aggregation:
| Aggregation | What it computes |
|---|---|
sum (default) | Total quantity across all events in the period. |
max | Maximum single-event quantity in the period. |
last_during_period | The quantity of the most recent event. Useful for “current seat count.” |
unique_count | Number of distinct external_id values (deduped). |
Late events
Events whose timestamp falls in a closed period are late. Two
behaviours:
| Component setting | Behaviour |
|---|---|
late_events: next_period (default) | Late events apply to the next open period. Simple, predictable. |
late_events: rebill | The closed period’s invoice is voided and re-issued with the late events included. A credit note is automatically posted for the void; the new invoice replaces it. |
rebill only applies if the original invoice has not yet been paid; once
paid, late events go to the next period regardless.
The 24-hour window after period close is the practical deadline for
rebill. Configure on the plan component.
Inspecting
Read the running totals for the current period:
GET /v1/subscriptions/{id}/usage?period=current{ "period": { "start": "2026-05-01T00:00:00Z", "end": "2026-06-01T00:00:00Z" }, "meters": [ { "meter": "api_calls", "quantity": "84219", "events": 84219 }, { "meter": "compute_seconds", "quantity": "12.7", "events": 18 } ]}Use period=closed&closed_at=2026-04-30 to get a closed period’s totals.
Best practices
- Post one event per countable action when feasible. The aggregator is
cheap; sending one event with
quantity: 1000works but loses the audit trail per action. - Always send an
external_id. Retries are routine. - Don’t rely on event order. Aggregations are commutative; out-of-order delivery doesn’t change the total.
- Use
last_during_periodfor state, not for counts. “Current seat count” is state. “Number of seat changes” is a count — usesumwith delta events.
Where to next
- Report metered usage — the integration recipe with code samples.
- Pricing models — how usage totals get priced.