Documentation
Network · Credits
Credits
Credits are the usage-accounting balance for Basis inference and API calls. A job's charge is deterministic — but how many $BASIS base units a credit costs is set by a versioned pricing epoch and locked into a snapshot at quote time. The network does not promise one credit maps to the same amount of $BASIS for all time.
What credits are
A credit balance represents usage accounting for inference and API calls. It is not a deposit account the network holds on a user's behalf as funds — Basis takes no custody. The balance is the unit of account that the deterministic pricing math draws down as jobs run.
The core principle
Credits are Basis's usage-accounting unit. They are deterministic inside a quote, reservation, pricing epoch, and receipt, but the network does not promise that one credit maps to the same amount of $BASIS forever.
Dynamic pricing epochs
BASIS-per-credit is set by a versioned pricing epoch — a dated, identified record of the active rate, the per-model credit prices, and the multipliers in force. Only the active epoch prices new quotes and reservations; superseded epochs are retained for audit and for the receipts locked under them.
BASIS-per-credit can adjust over time based on token market price, model cost, network utilization, worker supply, demand, provider reward floors, and operator-approved pricing epochs.
Token market price
When a price source is configured, BASIS-per-credit derives from a credit's target USD value divided by the BASIS market price. Until a token, liquidity, and a price source exist, no live price is fabricated.
Model cost
Each model carries its own per-token credit price and a multiplier in the epoch's model price table.
Utilization, supply & demand
Network load, worker supply, and request demand each apply as basis-point multipliers, prospectively, on new quotes.
Provider reward floor
A floor on the worker-pool share, so a contributor's reward never falls below the configured minimum for that epoch.
Capped epoch change
Every epoch-to-epoch move in BASIS-per-credit is clamped to maxEpochChangeBps, so no single step can spike the rate. All of it is bigint, basis-point, floor-division math — no floating point.
No retroactive repricing
Pricing changes apply prospectively to new quotes and reservations only. Existing receipts are never rewritten. A new epoch supersedes the previous one going forward — it does not reach back and reprice a job that was already accepted.
Pricing runs in a placeholder epoch until the $BASIS token, liquidity, and a price source exist. The math is real and the epoch value is mutable, but no live token price is fabricated. The machine-readable epoch, rate, and model table are served by the pricing API — API reference. The $BASIS token itself is planned, not live.
Quote / reservation locks the price (TTL)
Before a job runs, Basis locks a pricing snapshot. That snapshot records the active epoch, model price, multipliers, BASIS-per-credit rate, and quote expiry. The job receipt uses that snapshot, so users are not silently repriced and workers are not paid from a different formula after the fact.
Locked at reservation
A quote is deterministic for a given epoch and inputs: re-quoting under the same epoch and inputs produces identical raw amounts. When a job is reserved, that snapshot is frozen — the active epoch can move on afterward without touching the accepted job.
Held for the quote TTL
Each quote carries a short quote TTL (a created_at → expires_at window). Within the TTL the locked rate is honored; past it the quote is expired and must be re-quoted at the then-active epoch. A stale quote is never honored.
Receipts preserve the snapshot
The locked snapshot is carried onto the inference receipt as its hashed economic core. The receipt's total charge equals the snapshot's required $BASIS amount, and the worker reward is drawn from the same locked snapshot — the identical rate, multipliers, and worker pool — never a formula applied after the fact.
One snapshot, two protections
- Users are not silently repriced. The price is locked at reservation and preserved on the receipt for the quote TTL.
- Workers are not underpaid. The reward is drawn from the same locked snapshot plus the epoch's provider reward floor — not a later, different rate.
The full receipt shape, the canonical-JSON hashing scheme, and how to re-derive the hash yourself live under Inference receipts.
Credits → $BASIS
Usage is priced in credits — per token, per model — and credits convert to $BASIS base units at the active epoch's rate (basisPerCreditRaw). The credit cost of a job depends only on the model and the authoritative token counts; the credit → $BASIS rate is the layer that can move between epochs, always within the capped epoch-to-epoch bound.
Placeholder epoch — tunable, not a promise
- basisPerCreditRaw = 1,000,000,000,000,000 (1e15 = 0.001 $BASIS), 18 decimals
- creditTargetUsdRaw = 10,000 (micro-USD = $0.01 / credit)
- basisUsdPriceRaw = null (no price source — never fabricated)
- all multipliers = 10000 bps (1.0x) · maxEpochChangeBps = 2500
These are tunable placeholders so the deterministic math has concrete inputs — not final pricing, not a quote, and not a promise of any future $BASIS value. The placeholder rate happens to match the retired fixed unit, but it is now a mutable epoch value, not a constant. Real pricing is a launch decision and an explicit operator action. Full spec: docs/pricing-policy.md.
The one place a live market quote is needed is converting a sell token — ETH, WETH, or USDC — into the required amount of $BASIS at payment time. That conversion, and only that conversion, uses a fresh exact-output quote (next section).
Paying with tokens
You can fund credits two ways. Deposit $BASIS directly, or route ETH / WETH / USDC into $BASIS at payment time. ETH/WETH/USDC payments use a fresh exact-output quote to acquire the required amount of BASIS at payment time — bounded by a TTL and a slippage floor so a stale or unfavorable quote is never honored.
Quote-time price
The sell-token → $BASIS leg is priced from a fresh market quote requested at payment time via POST /api/payments/quote. Basis does not assume a price between requests; each quote is current and short-lived. This is a separate market leg from the credit → $BASIS pricing epoch.
Quote TTL + slippage
Every quote carries an expires_at (a short TTL, currently 90s) and a min_basis_out_raw floor derived from slippage_bps (default 100, ceiling 300). After the TTL the quote is expired and refused; below the floor the swap reverts rather than under-delivering $BASIS.
A quote links a deposit
A confirmed quote is bound to the resulting deposit: it is single-use, so re-confirming the same quote_id is rejected (409 duplicate_payment) and the deposit cannot be double-counted. On-chain verification is pending, so a confirmed credit is provisional. The full route surface lives in the API reference.
Paying requires an authenticated, linked wallet
When authentication is required, you must be signed in (Privy) and may only quote or pay for a wallet linked to your account. /api/payments/prepare and /api/payments/confirm bind to your linked payer wallet, so credits fund the wallet you signed in with — paying for an unlinked wallet is rejected (403 wallet_not_linked).
Deposits & pending state
Credit deposits
Deposits pendingvault: PendingUsers may deposit $BASIS to fund credits once the token and the credit vault are configured. Until then, depositsEnabled() returns false, and credit balances may be internal and pending rather than backed by an on-chain deposit. The accounting still runs; it is simply not yet settled against a deployed vault.
Credit lifecycle
Reserve (estimated, price locked)
When a request is accepted, Basis locks a pricing snapshot (active epoch + rate + multipliers + expiry) and reserves an estimated charge against the caller's available credits so two concurrent jobs cannot spend the same balance.
Debit (actual)
When the job completes, the actual credit usage is computed deterministically from the real prompt and output token counts, converted to $BASIS at the locked snapshot rate, and debited.
Release / refund (unused)
The difference between the reserved estimate and the actual debit is released back to available credits. A failed job releases the full reservation — it does not overcharge.
The result: a failed job never overcharges. A job is only ever debited for what it actually consumed, priced at the snapshot it was reserved under, and anything reserved beyond that is returned.
Determinism & units
All amounts are integer base units, carried as decimal strings and computed with big-integer math and floor division. There is no floating point anywhere in the money path, so a request, its locked snapshot, and its receipt always agree — to the last unit, for the life of that quote.
Units (placeholder economics — not final)
- $BASIS amounts = 18-decimal base units (wei-like)
- USD amounts = micro-USD (1e-6 USD) integers
- credits = raw integer credit base units
- multipliers = basis points (bps; 10000 = 1.0x)
- protocolFee in bps · all division is floor (bigint)
These are tunable accounting placeholders so the deterministic math has concrete inputs. They are not final pricing; real pricing is a versioned, operator-approved launch decision.
Charge derivation (per locked epoch, floor division, bps)
- usageCredits = (promptCredits×promptTokens + outputCredits×outputTokens) × modelMultiplier / 10000
- basisRequired = usageCredits × basisPerCreditRaw (from the locked snapshot)
- protocolFee = basisRequired × feeBps / 10000
- workerPool = basisRequired − protocolFee (≥ provider floor)
Worked example
Model basis-default (multiplier 10000 bps = 1x), with 1000 prompt tokens and 500 output tokens, priced at the placeholder epoch's locked snapshot. All values are $BASIS base units. Prices are placeholder economics, not final.
epoch epoch-placeholder-001 (basisPerCreditRaw = 1e15)
model basis-default (modelMultiplier = 10000 bps = 1x)
promptTokens 1000
outputTokens 500
# usage priced in credits, then converted to $BASIS at the LOCKED snapshot rate
promptCharge = 1000000000000 * 1000 * 10000 / 10000
= 1000000000000000 # 1e15
outputCharge = 4000000000000 * 500 * 10000 / 10000
= 2000000000000000 # 2e15
total = promptCharge + outputCharge
= 3000000000000000 # 3e15 (basisRequired at this epoch)
protocolFee = total * 1000 / 10000 # 10%
= 300000000000000 # 3e14
workerPool = total - protocolFee
= 2700000000000000 # 2.7e15 (>= provider floor)The user's credit balance is debited the total (3e15 base units), priced at the snapshot the job was reserved under. The protocol fee (3e14) is withheld, and the worker pool (2.7e15) — drawn from the same locked snapshot — is what a contributor worker's reward is computed from on the receipt. A later epoch would not change this receipt.
Reading a balance
Available credits for an address are returned as a raw $BASIS base-unit string. The response also reports whether deposits are enabled.
curl -s https://basis.watch/api/credits/0xYourAddress
# {
# "address": "0xYourAddress",
# "balanceRaw": "2700000000000000",
# "tokenSymbol": "BASIS",
# "depositsEnabled": false
# }The active pricing epoch, the BASIS-per-credit rate, and the per-model credit table are served by the pricing API — see the API reference. The $BASIS token is planned, not live.