How charging works, and why a failed task costs nothing
Reserve, settle, release. A walk through the three steps behind every Tovano charge, and what they mean for your balance.
Usage-based billing is only useful if you can trust it. A customer who pays per image wants to know three things: what a call will cost before it runs, what it actually cost afterwards, and that nothing was charged for a call that did not work. This post explains how Tovano gets there.
Three steps behind every charge
Every task moves through the ledger in three steps.
- Reserve. When a task is accepted, we work out the most it can cost and hold that amount on your balance. For four images at $0.020 that is $0.080. For a chat request it is the input tokens plus the
max_tokensyou asked for. - Settle. When the task completes, we charge the real amount from the provider's result and release whatever was left of the reservation.
- Release. When the task fails, the whole reservation is released. The task shows
"status": "failed"and"charged_micro": 0.
The reservation is what makes the other guarantees possible. It means a request can only start if your balance covers it, and two tasks running at the same time can never spend the same dollar twice.
What you see in the API
Your balance has three parts:
{
"object": "balance",
"balance_micro": 84120000,
"reserved_micro": 80000,
"available_micro": 84040000,
"currency": "usd"
}
available_micro is what new tasks can use. reserved_micro is held by tasks that are still running. When they finish, the reservation turns into a charge or goes back to your balance.
Why an estimate and not a guess
For most models the estimate is exact. An image model charges per image, and the number of images is in the request. A video model charges per second, and the duration is in the request. Speech is charged per 1,000 characters of the text you send.
Text is the one case where the final number is lower than the estimate. We cannot know how long the reply will be, so we reserve for the full max_tokens and settle on what the model actually wrote. Setting a sensible max_tokens keeps more of your balance available while many chat calls run at once.
Agent jobs
An agent job runs several models in a row, and each step is charged on its own as it completes. If a later step fails, the job fails as a whole and the steps that already ran are refunded. The ledger shows the charge and the matching refund, so the history stays complete and the net cost is zero.
The ledger is append-only
Every change to your balance is one row in the ledger: topup, charge, refund, grant or adjustment. Rows are never edited or deleted. Your balance is the sum of the rows. If you ever doubt a number, you can trace it back, one row at a time, under Billing in the dashboard.
Rounding
All amounts are integers in micro-dollars, a millionth of a dollar. When a charge works out to a fraction of a micro-dollar, for example a few tokens of text, it is rounded up to the next whole micro-dollar. That is the only rounding we do, and it is at most $0.000001 per task.
In short
- You can see the most a task will cost before it runs.
- You pay for what the model delivered, not for what it might have delivered.
- If it fails, you pay nothing, and the task says so.