Architecture and responsibilities
ONR is responsible for:- extracting upstream usage according to the provider DSL;
- estimating usage when the upstream does not return it;
- calculating request-level prices from ONR pricing files;
- mapping an access key to a Meterry subject;
- persisting events in an outbox and retrying delivery.
- extractor rule-set field extraction;
- charge-item metering and pricing;
- accounts, wallets, subject routes, and usage limits;
- usage events, billing, and aggregate queries.
Authorization headers, upstream API keys, or traffic dumps to Meterry.
1. Prepare the Meterry project
Use the correct API host
The portal and API use different hosts:ONR_METERRY_BASE_URL must point to the API host:
https://meterry.com for ingest returns an HTML 404 page.
Create and publish an extractor rule set
Create an extractor rule set in the project’s Rules page and publish it before ingesting events. A draft rule returnsextractor rule set is not published.
ONR emits these normalized usage fields:
prompt_tokens and completion_tokens; these are the metric names used by ONR’s x-billing.items.
Use a dynamic amount expression
Token charge items must calculate their amount from quantity and price. Do not leaveamount_expr fixed at zero:
Configure the subject
By default, ONR uses the access-key name as the billing subject:2. Configure ONR
Keep credentials in.env or the deployment environment; do not commit them to Git:
onr.yaml:
only_billable_success: true reports only 2xx model requests. outbox_dir stores pending JSONL events, while the timeout and retry settings control delivery. fallback_subject_id is used for master-key requests or requests without a matching access key.
Validate the configuration and start ONR:
3. Event shape
ONR sends events to:x-billing.items makes the runtime token quantities the charge-item source of truth. x-billing.pricing_hints carries the provider/model/channel pricing calculated by ONR to Meterry.
4. Delivery, retries, and idempotency
The delivery flow is:onr:<request_id>. Failed events remain in the outbox and are retried, including after a process restart. Keep the same request ID on retries; generating a new one creates duplicate billing events.
5. Verify a real ingest
Use a fixed request ID for a smoke test:external_event_id, subject fields, token metrics, amount, unit price, raw_event_id, and usage_event_id.
6. User wallet balance enforcement
Meterry debits an account wallet when it processes a rated usage event. Keep account, wallet, credit, and subject-route management in the existing business backend:- Create one Meterry account and USD wallet for each access key.
- Bind
api_key/<access-key-name>to that account with a subject route. - Credit the wallet through
POST /v1/projects/:project_id/wallets/credit. - Keep the ONR event subject unchanged so Meterry can resolve the payer wallet.
402 Payment Required with an OpenAI-compatible error:
failure_mode: "closed" by default and reject the request with 503. Set failure_mode: "open" to allow requests while Meterry is unavailable. Requests without a mapped access-key subject, including master-key requests, bypass balance enforcement unless they are explicitly assigned a fallback subject.
Configure the webhook endpoint at POST /internal/meterry/webhook in ONR and register the same URL in Meterry. ONR verifies the HMAC-SHA256 signature, rejects stale timestamps, deduplicates webhook IDs, and persists subject state for wallet.insufficient_balance, wallet.balance_changed, wallet.available_balance.threshold_crossed, and usage_limit.exhausted.
Store webhook_secret in the deployment environment rather than committing it to Git:
7. Usage Explorer queries
Summary queries grouped by metric require an explicitmetric; otherwise Usage Explorer reports:
gpt-4o-mini, not gpt_4o_mini. Use Events to inspect individual records and Summary with a metric to inspect aggregate amounts.
8. Troubleshooting
HTML 404 from the API
Set the base URL tohttps://api.meterry.com, not the portal URL.
extractor rule set is not published
Publish the extractor rule set from the project’s Rules page.
Event accepted but Usage Explorer is empty
Check that the rule is published, subject fields are present and routed, rule paths matchraw_json, charge-item metrics match x-billing.items, the query specifies a metric, and the time range covers occurred_at.
Token quantity exists but amount is zero
Replace a fixeddec('0') amount expression with the dynamic quantity / pricing_unit * unit_price expression shown above.
Outbox never drains
Check the API host, project/API-key/rule-set consistency, published status, the API key’susage:ingest scope, and network access from the ONR process.
Balance checks reject every request
Confirm the access key has a matchingapi_key/<name> subject route, the account has a USD wallet, the wallet balance is positive, and the configured project API key can read realtime wallet amounts.
Webhooks return 401
Check that the raw request body is signed, the timestamp is withintimestamp_tolerance_s, and webhook_secret exactly matches the secret configured for the Meterry webhook endpoint.