Billing rules
This page documents primerouter's billing mechanism, edge cases, and refund policy.
Billing timeline
| Phase | Behavior |
|---|---|
| Request arrives | Pre-charge by estimated max (prevents overspend) |
| Request succeeds | Settle by real usage, refund the difference |
| Request fails | Pre-charged amount fully refunded |
| Stream interrupted | Settle by tokens received in chunks so far |
Pre-charge factor = max_tokens × 1.2 (default; site administrators can adjust this from the backend)
How tokens are counted
primerouter doesn't count tokens itself — it uses upstream's usage field directly:
- prompt_tokens: upstream-counted input tokens
- completion_tokens: upstream-counted output tokens
- byte-identical to upstream's bill
See Usage analytics.
Multimodal billing
| Type | Billed by | Notes |
|---|---|---|
| Text | input + output tokens | Standard |
| Vision input | counted as input tokens | Each provider tokenizes images differently — passed through |
| Image generation | count × per-image price | Token-independent |
| Video generation | duration (sec) × per-sec price | Async — billed by completed result |
| Audio TTS | character count × per-char | |
| Audio STT | input audio seconds × per-sec |
Failure / retry
If primerouter routes to upstream A (fails) then auto-retries upstream B (succeeds), only B is charged once.
All upstream-side cost from intermediate failures (e.g. A streamed out tokens before crashing) are absorbed internally — no double charge.
Rate limit not billed
Rate-limited (429) requests are not billed.
Cancel request
| Situation | Behavior |
|---|---|
| Streaming client disconnect | Upstream typically continues to completion — billed by real output |
Explicit abort | Upstream socket closed (when supported), billed by tokens generated so far |
| Async task (video / music) cancellation | Free if cancelled before "generating"; billed if started, depending on upstream cancellability |
To save on streaming requests: when client aborts, explicitly close the HTTPS socket. Upstream keeps generating during natural timeouts.
Refund policy
primerouter does not support top-up refunds by default — quota is consumable only, not withdrawable.
Exceptions:
- Double charge: system bug-caused duplicate charge — provide trace_id from Logs to support; verified, refunded as quota
- Operator error: e.g. admin mistakenly deleted balance, wrong multiplier
- Crypto wrong chain etc.: best-effort recovery, see Crypto FAQ
Refunds are made to on-site quota (balance increase), not to the original payment method.
Async task pre-charge writeback
Long tasks (video / music):
- Pre-charge by estimate at submission (e.g. $5)
- Settle by real result on completion (e.g. $4.20)
- Difference ($0.80) refunded to balance
Failed tasks: full refund.
Cross-day / cross-month accounting
Counted to the date when settlement happens. A streaming request's tokens belong to the completion-time day, even if it spans midnight.
Quota units
Sites can configure internal units:
- USD: shows USD directly (default)
- CNY: yuan
quota: abstract internal unit (1:1 with currency or fixed ratio)
The base currency is set by site administrators from the backend.
Min top-up
Each payment method has a minimum (typical $5–10). Below-min payments are not credited — crypto top-ups will retain the on-chain record but won't settle.
Does balance expire?
Standard account balance doesn't expire. But:
- Account deleted: balance forfeited
- Long-inactive accounts: site reserves the right to clean up per compliance (≥ 12 months inactive)
Billing transparency
Every Logs row can be expanded to show:
- Your request → which upstream → upstream usage field → actual charge
If actual charge doesn't equal usage × price × multiplier, send the trace_id to support. This is the programmatic basis for the "no token inflation" commitment described in Architecture.
