Billing model
AIx is prepaid. You buy credits; each call is settled against them. The design goal: you are never overcharged, and we never silently lose a charge.
Credits
- 1 credit = $1 USD.
- Your balance lives in one column (
api_keys.total_credits) and is the single source of truth for billing. - Top up with Razorpay or PayPal — see Billing & credits.
The estimate → settle flow
Every billable call follows the same lifecycle:
- Estimate — the input is tokenized (tiktoken) and priced to a conservative cost estimate.
- Guard — per-key policy is checked: moderation, scopes, spend caps, TPM (see Limits, caps & scopes).
- Deduct — the estimate is deducted in a single atomic UPDATE that also verifies the key is active, unexpired and has enough balance. One round trip on the happy path.
- Call — AIx executes the request through a healthy route (with failover).
- Settle — the call is re-priced on the route’s reported usage, and the
difference (
estimate − actual) is refunded.
estimate hold ──► model call ──► settle on real usage ──► refund the difference
│ │
└── on execution error: refund the entire hold
Because we hold an estimate and refund the unused part, successful calls settle to reported usage. If a route omits usage, AIx falls back to the preflight estimate.
Audio is special
Audio transcription (STT) is billed on the real transcript duration, not a file-size guess:
- If real duration < estimate → the difference is refunded.
- If real duration > estimate → the extra is charged after the fact. If the balance can’t cover it, the call already succeeded, so the shortfall is queued for reconciliation rather than failed.
Reconciliation — money is never lost
Refunds and post-hoc charges are themselves OCC-retried, but if one still can’t complete,
the amount is written to a billing_reconciliation queue instead of vanishing:
| Situation | Signed amount | Meaning |
|---|---|---|
| A refund failed | positive | We owe you credits back. |
| An extra charge couldn’t be collected | negative | We under-charged. |
An operator settles these rows. The invariant: a discrepancy is always recorded, never swallowed.
Concurrency (Aurora DSQL OCC)
The balance lives in Aurora DSQL, which uses optimistic concurrency control: two calls
billing the same key at once can collide at commit with a serialization error. Every balance
mutation is wrapped in an OCC retry, so heavy concurrent traffic on one key doesn’t
surface as a spurious 500.
Idempotency
Send an Idempotency-Key header with POST /v1/chat/completions to make retries safe.
A repeated non-streaming call with the same key (within 24h) replays the completed result;
streaming uses it as a single-use duplicate guard because a stream body cannot be replayed.