Permalink to Credits and billingCredits and billing
An account holds exactly one balance and it is denominated in credits. There is no separate dollar wallet, no per-vendor sub-balance and no prepaid pool per modality. Every image, second of video, thousand tokens and second of audio comes out of the same number.
Current prices live on the pricing page and, per model, in
pricing.credits on the model card. This page describes the mechanism,
which does not change.
Permalink to how-a-call-is-pricedHow a call is priced
- The model's rate card gives a base rate for whatever it charges by — per image, per request, per second of video, per thousand tokens, per thousand characters, per second of audio.
- Ratio tables multiply that:
size_ratio,quality_ratio,resolution_ratioandflag_ratioare pure multipliers on the headline rate, so a 1080p second and a 480p second of the same model are the same rate scaled differently. Long-context models add atoken_tiersladder keyed onmin_prompt_tokens. - The result becomes the model's offering price, and that price is projected onto the credit scale by a fixed platform constant, bent by a per-model multiplier we use for promotions and premium tiers.
- Credits are quantised to four decimal places — the same grid the ledger settles on.
Step 3 is why the API publishes pricing.credits alongside the USD figures, and why a client must
read it rather than compute it: the per-model multiplier is deliberately not exposed, so any
arithmetic done on the dollar figures will be wrong exactly on the models where being wrong costs
money.
Routing never changes your price. We may serve the same model from any of several upstreams depending on capacity and health, and those upstreams charge us differently — but the customer price is fixed by the model, not by whoever happened to answer.
Permalink to synchronous-callsSynchronous calls
/v1/chat/completions, /v1/audio/speech and /v1/audio/transcriptions are priced after the
upstream answers, from the usage it reported, and debited in a single local transaction along with
the request log. Either the whole thing commits or none of it does.
Before the call goes out, a balance check refuses anything you cannot pay for. That check does not
fail open: if the ledger cannot be read, the request is refused with 503 precheck_failed rather
than served unmetered.
Permalink to asynchronous-jobsAsynchronous jobs
Because a job's real cost is not known until it finishes, submitting one reserves credits from an estimate:
submit ─► reserve est_credits (balance drops immediately)
terminal ─► succeeded → settle to the real figure
failed → refund everything taken
queue_expired → refund everything taken- Under the estimate. The difference is refunded.
- Over the estimate. The difference is charged. A final settlement is allowed to push the
balance slightly negative — an incurred cost is always recorded — and shows up as an
overdraftentry that the next grant absorbs. - Failed or queue-expired. Everything actually taken comes back, in full. The job's cost columns go to zero while the estimate stays on the row as the audit trail of what was reversed.
That last rule covers the awkward case too: if an upstream generated something but we could not deliver a downloadable artifact, the job fails and you are refunded. You are never charged for a result you cannot fetch.
Refunds are returned to the same grants the debit drew from, never as a fresh grant. That is why a refunded subscription credit keeps its original period expiry, and a refunded pack credit keeps its lack of one.
Each of the three money movements on a job — the reservation, the adjustment, the refund — is guarded by an idempotency key, so a retried poll or a duplicated upstream callback cannot charge or refund twice.
Permalink to where-credits-come-from-and-the-order-they-are-spentWhere credits come from, and the order they are spent
Two sources:
- a subscription grant, refreshed each billing period and expiring with it;
- credit packs, bought as a one-off, which do not expire.
Spending draws down the subscription grant first, then packs. That ordering is deliberate: it spends the credits that would otherwise lapse before the ones that keep.
Permalink to no-overdraft-on-the-way-inNo overdraft on the way in
There is no "spend now, settle later". The moment your balance cannot cover the next call, that call does not happen:
{
"error": {
"message": "this call costs about 41.6 credits and you have 3.2; top up or upgrade your plan to continue",
"type": "insufficient_quota",
"code": "insufficient_credits",
"param": null
}
}HTTP 402. On an asynchronous submit the same check runs before the job is created, so a 402
there means nothing was reserved and nothing was queued.
Estimates are conservative on purpose
A job's reservation is quoted from what the request could cost — including axes the request body cannot express, like a model that generates an audio track by default and doubles its per-second rate. A conservative estimate refused up front is recoverable; an upstream bill for a clip the customer could not afford is not.
Permalink to reading-your-balanceReading your balance
Balance, ledger and usage are account endpoints, not API endpoints. They live under
/api/hub/billing/* and require a signed-in browser session — an sk-hh- key is deliberately not
enough to read or spend an account's money outside /v1.
Open the account dialog on hypit.ai for:
- Credits — current balance, split into subscription, pack and overdraft, plus the plan and when it renews;
- Billing records — the ledger, one row per grant, debit, adjustment, refund and expiry;
- Usage — credits and request counts rolled up by day, by model and by modality.
Usage windows are computed in UTC+8, which is the billing day this product uses everywhere.
There are no cost headers on `/v1` responses
If you are used to x-ratelimit-remaining-* or a per-response cost header, there is none here. A
call's consumption is visible in the response body's usage object where the upstream reports one,
and authoritatively in the account dialog's usage view. The only headers we add are X-Request-Id
and, on a refusal, Retry-After.
Permalink to free-modelsFree models
A model card may carry "free": true in its pricing, in which case both the dollar figure and the
credit figure are zero. A free model still requires a non-empty balance to call — the gate asks
"is there anything left at all" — and still counts against your rate and concurrency limits.