Quotes and credits
How pricing and charging work — you always see the price before you pay.
Paid actions in roasOS follow one simple rule: you see the price before you’re charged.
The quote → confirm flow
Every paid request happens in two steps:
- Quote — ask for the price. Set
quote_only: true. This is free and never charges you. You get back aquote_idand the price inreserved_credits. - Confirm — run it. Send the same request with the
quote_idinstead ofquote_only. This is the only step that spends credits.
Idempotency keys
Every paid request needs an Idempotency-Key header — any unique string, 16–255 characters. It makes retries safe: if you send the same request twice with the same key (say, after a network timeout), you get the same result and are charged once.
Use the same key for the quote and its confirm.
-H "Idempotency-Key: order-12345-image-1"
Quotes expire
A quote is valid for 10 minutes. After that, confirming it fails and you just request a fresh quote. Quotes are locked to the exact request you priced — you can’t change the prompt or model between quoting and confirming.
Reserved vs. charged
- When you confirm, credits are reserved (held).
- On success, the reservation is captured — you’re charged.
- On failure (provider error, timeout, etc.), the reservation is released — you’re not charged.
You can see your balance any time at GET /v1/account:
{
"credits": {
"available": 1570,
"reserved": 0,
"pending_refunds": 0
}
}
Approval thresholds
If a request costs more than your key’s approval threshold, the quote comes back with authorization.status: "approval_required" and a link to approve it. Smaller requests are auto_approved. Set thresholds per key in your settings.
Seeing what you spent
GET /v1/account/usage— a list of each charge.GET /v1/account/ledger— the full billing record, including reservations and refunds.GET /v1/account/usage/summary— totals grouped by day.