What a 402 means, how holds work, why a balance can look stale for a moment, and what happens when a request fails.
Everything on this page describes enforced platform behavior — not best-effort intentions. If you observe something different, report it.
402 insufficient_credits#Your balance can't cover the request's pre-flight estimate.
GET /api/v1/credits.:free model works at 0 DA; if a free model errors, it's the model being busy upstream (429), not your wallet.Streaming requests place a hold before the stream starts: an estimate based on your prompt size and the model's maximum output. When the stream finishes, you're charged only for the tokens actually processed and the rest of the hold returns instantly.
/v1 API responses, the X-Balance-Available header reflects your balance at response time; the charge for that very call lands right after the response is sent, so the header catches up on your next call.Deposit confirmation is idempotent: the same order can be confirmed any number of times (page refresh, bank redirect replay) and credits exactly once. A deposit that first failed and later succeeds on retry credits the same record — you'll never see duplicates or double credits.
429 errors#Two different things return 429:
| Source | Shape | What to do |
|---|---|---|
| Your key's rate limit | error: rate_limit_exceeded with retry_after and X-RateLimit-* headers | Wait for the window (X-RateLimit-Reset) or raise the key's limit in Dashboard → Keys |
| The model itself is busy | rate_limited in the chat stream / upstream error via the API | Try again shortly or pick another model — you are not charged for these |
Chat conversations are limited to 30 messages per minute per account across all models.
No. A request that fails upstream (model error, rate limit, outage) charges nothing — holds are released in full. Partial streams charge only what was actually generated. Every charge you do see maps to a ledger entry in Dashboard → Activity with the exact DA amount.