Report metered usage
For any subscription with a usage component, you push events as your
customers consume — Paylera aggregates at period close and prices the
total.
The minimal call
POST /v1/usageIdempotency-Key: <uuid>{ "subscription_id": "sub_…", "meter": "api_calls", "quantity": "1", "timestamp": "2026-05-06T12:34:56.789Z", "external_id": "req_8f4a…"}That’s the entire interface. Throw away the response body — a 202 means we have it.
Always send external_id
This is your dedupe key. Two events with the same
(subscription_id, meter, external_id) are merged silently. Use:
- Your service’s request ID, for per-request metering.
- Your job ID, for batch jobs.
- A combination of
(user_id, action, day_bucket)for daily snapshots.
If you don’t send one, retries create duplicates. There is no second chance.
Batching
Send up to 1000 events in one call:
POST /v1/usage/batchIdempotency-Key: <uuid>{ "events": [ { "subscription_id": "sub_…", "meter": "api_calls", "quantity": "1", "timestamp": "…", "external_id": "req_1" }, { "subscription_id": "sub_…", "meter": "api_calls", "quantity": "1", "timestamp": "…", "external_id": "req_2" }, … ]}Batched calls are atomic per call: either all events accept or none do. Use this from your aggregation pipeline, not from request-handling code.
Quantity is decimal
"quantity": "0.001" is fine. "quantity": "-1" (correction) is fine.
"quantity": "1.0e3" is rejected — send "1000".
Timestamps and periods
The event’s timestamp decides which period it belongs to. Default
behaviour for events landing in a closed period: see
Metered usage → Late events.
For best results, send timestamp in UTC ISO-8601 with millisecond
precision. The aggregator ignores sub-millisecond resolution.
Late events
Two policies, set on the usage component:
next_period(default) — late events apply to the next open period. Predictable, simple.rebill— the closed period’s invoice is voided and re-issued with the late events folded in. Only available within 24 hours of close, and only if the invoice has not been paid.
Most teams pick next_period for the simplicity. Pick rebill only if
your customers genuinely care about the right total appearing on the
right month’s invoice.
Inspecting
GET /v1/subscriptions/{id}/usage?period=current{ "period": { "start": "…", "end": "…" }, "meters": [ { "meter": "api_calls", "quantity": "84219", "events": 84219 } ]}For a closed period:
?period=closed&closed_at=2026-04-30
Estimating cost
Mid-period, you can preview what an invoice would look like if the period closed now:
GET /v1/subscriptions/{id}/upcoming-invoiceThis walks the same pricing engine, applies discounts, computes tax, and returns a draft invoice — useful for in-app “current usage” widgets.
What to send (and what not to)
| Send when | Don’t send when |
|---|---|
| A countable, billable action completes successfully. | The action failed or was rolled back. |
| A user opens a feature, if you charge per open. | A page renders with the feature visible. |
| A scheduled job runs to completion. | A scheduled job starts. |
| The customer’s seat count changes. | Every authentication. |
Error cases
| Status | Meaning |
|---|---|
| 202 | Accepted; will be aggregated. |
400 usage.invalid_quantity | Quantity wasn’t a decimal. |
404 usage.subscription_not_found | Subscription doesn’t exist or isn’t yours. |
409 usage.subscription_canceled | Subscription is canceled or ended; events rejected. |
422 usage.meter_not_on_subscription | The meter isn’t in any of the plan’s components. |
Don’t drop a 409 silently — you may be metering against a
subscription you’ve forgotten to deprovision, which means you’re doing
work you’ll never bill for.
Webhook events
Paylera does not emit webhooks per usage event — too noisy. You’ll see usage reflected in:
| Event | When |
|---|---|
subscription.usage_threshold_crossed | If you’ve configured per-component alerts (e.g. “ping me at 80% of included quota”). |
invoice.finalized | At period close; the invoice carries the aggregated usage line. |