Billing and packages
Prepaid packages, exact quantities, no subscriptions and no overage. This page explains the mechanics; the catalogue holds the numbers.
Prepaid, not subscribed
You buy a package. It grants a quantity that lasts for a published lifetime. When it is spent or expired, requests stop with a 402 and a clear code — they do not continue and become a bill.
Nothing renews automatically, nothing is stored for future charges, and there is no monthly invoice to cancel. The worst case for a leaked key or a runaway script is the package you have already paid for, which is the entire reason the product is shaped this way.
Two billing modes
Token quota packages grant Tokens. New model-visible input and generated output consume Tokens 1:1. When SP Cambo locally recognizes a repeated prompt prefix, those cached input Tokens consume 0.25× instead. There is no hidden output weight or provider-controlled multiplier.
Credit balance is money-style wallet credit and is priced from the same local input/output counts. Dollar-denominated quota Credit packages shown in the catalogue use the published conversion $1 Credit = 100,000 Tokens.
Which mode a package uses is stated on the pricing page , along with the aliases it covers.
Local cache-aware metering
SP Cambo measures model-visible input and delivered output at its own public gateway. New input and output are 1:1. A repeated prompt prefix detected by SP Cambo's local cache is billed at 0.25×. For example, 20,000 new input Tokens + 80,000 cached input Tokens + 500 output Tokens settles as 20,000 + 20,000 + 500 = 40,500 Tokens.
The local cache is scoped to the API key, public model and API protocol. It requires at least 1,024 matching Tokens and uses a five-minute reuse window. Only SHA-256 segment hashes and token estimates are kept in the gateway cache; prompt text is not stored there. Failed/rejected inference attempts do not seed the cache.
OmniRoute/provider usage, provider cache hits, reasoning counters and cost counters are never accepted as customer billing input. The local count is tokenizer-like and deterministic, so it can differ somewhat from a vendor's private tokenizer while remaining stable for the same public request/response.
From payment to spendable quota
- Choose a package. Every package publishes its quantity, price, exact lifetime, eligible model aliases and limits before you pay.
- Pay by KHQR. An order is created and a Bakong QR is issued with a real expiry. The countdown comes from the server clock, not your device.
- Verification. SP Cambo confirms the payment against the payment network. Nothing you press in the browser can mark an order paid.
- Entitlement lots. A verified payment creates lots with a start, an expiry and a remaining quantity. Fulfilment is idempotent: one payment credits you exactly once.
- Spend. Requests reserve, execute and settle against your lots until they are exhausted or expired.
Entitlement lots and FEFO
Your balance is not one opaque number. Each purchase creates its own lot with its own quantity, start and expiry. Buying a second package while the first is still live gives you two lots, not a merged total.
Consumption is first-expiring-first-out: the lot that expires soonest is spent first, so nothing is wasted while a later-expiring lot sits idle. Your entitlements view lists lots in the order they will actually be consumed.
An expired lot never becomes spendable again, and neither does a revoked one. Quantity left in a lot when it expires is gone; that is what a lifetime means.
How lifetimes are measured
Lifetimes are exact seconds from activation. A one-day package is 24 hours from the moment payment is confirmed, not until midnight. Timestamps are stored in UTC and displayed in your timezone.
Every package publishes its lifetime before you buy, and your dashboard shows the real expiry timestamp of each lot rather than a rounded phrase.
Reserve, execute, settle
SP Cambo does not check your balance and then hope. Each request reserves a safe local maximum before inference, taking any SP Cambo local-cache discount into account, then settles the locally metered usage and releases the remainder in one atomic step.
This is why concurrent requests cannot overspend a nearly-empty package, and why a large max_tokens can be refused up front: the reservation has to fit.
Between execution and settlement, an activity row is marked estimated. An estimated figure is never what you are charged — it is the reservation, shown so the page is not blank while the request finishes. It is replaced in place when settlement lands.
If a request fails in a way that qualifies for a refund, the reservation is released exactly once. Rejected requests — bad key, unknown alias, exhausted package, rate limit — never reserve anything at all.
Exact numbers, never floats
Money is transported as integer minor units with an explicit currency and exponent. Token and credit quantities are integer strings. Nothing in the billing path is a binary float, because binary floats cannot represent decimal money exactly and small errors accumulate over millions of metered units.
If you consume these values programmatically, keep them exact. Parsing them into a double-precision number to display them is where rounding errors come from.
The ledger
Every movement of quota or money is an append-only ledger entry with an idempotency key. Nothing is edited in place and nothing is deleted, so your history reconciles.
| Entry | Meaning |
|---|---|
purchase | A verified payment created one or more entitlement lots. |
reservation | Budget was held for an in-flight request. |
settlement | Actual metered usage was charged. |
reservation_release | The unused part of a reservation was returned. |
refund | A charge was reversed. |
promo_grant | A promotion granted quota or credit. |
expiration | A lot passed its expiry with quota remaining. |
admin_adjustment | A manual correction, recorded with its reason. |
Duplicate payment callbacks and repeated verification checks cannot duplicate money or quota. Ask SP Cambo to re-check a payment as often as you like.
Payments
Payment is by Bakong KHQR. The QR carries a real expiry; the countdown you see is corrected against the server clock so a wrong device clock cannot mislead you.
The "I have paid" action asks the backend to re-verify. It is a request for a check, not an assertion of success — nothing in the browser can credit an account. If verification has not landed yet you will see payment_pending, which is a normal intermediate state.
If a QR expires before you pay, start a new order. Do not pay an expired QR.
Pricing changes and your history
Each usage record snapshots the pricing rules that applied at the time. A later catalogue change does not retroactively rewrite what you were charged, and your historical usage stays consistent with the balance movements beside it.
What is recorded against your account
Request metadata: alias, key, timestamps, duration, token counts, settlement state and the ledger entries above. Prompts, completions, tool payloads and file contents are not stored. See usage for exactly what is retained.
Quota and balance errors are documented in errors .