# Pricing and billing

You pay in Credits, bought in US dollars. Video is priced per second of output, images per image, by the tier your input selects.

## Credits

Credits are bought in packs from the console. The standard pack is $10 for 2,000 Credits, so 1 Credit is $0.005; larger packs add bonus Credits. Every API amount is in Credits, written with three decimals as a string, for example `"157.000"`.

## How a task is priced

Each model has price tiers, listed by [get a model](/docs/api/getModel) and on the model's page. Your input selects the tier, usually by its resolution and whether it includes a video.

| Tier type | Price | Example |
| --- | --- | --- |
| Per second | Credits per second of output | Kling 4.0 720p: 31.4 Credits per second ($0.157) |
| Per second with input video | Credits per second of input plus output | Seedance 2.5 720p with video: 34 Credits per second |
| Per image | Credits per output image | Seedream 5.0 Pro: 20 Credits per image |

A task's price is the rate times the seconds it asks for. A 5-second Kling 4.0 video at 720p is 5 × 31.4 = 157.000 Credits.

> **Note**
> When a model chooses the length itself (for example `duration: -1`), the hold covers the longest length the tier allows and the charge follows the actual usage of what was produced.

## Estimate first

Send the same body to [estimate a price](/docs/api/createEstimate) to get the exact Credits a create would hold, with the seconds or images it priced. An estimate creates no task and holds nothing. Prices can change between an estimate and a create.

## Hold, charge and release

1. **Accepted.** The create answers HTTP 202. The task's `price.estimated` is the amount to hold.
2. **Held.** When funding succeeds, the Credits move from your available balance to held, and `price.reserved` shows them. If funding fails, the task closes with `insufficient_balance`, `balance_negative`, `budget_exceeded` or `spending_blocked` and nothing is held.
3. **Charged.** A succeeded task is charged `price.charged`, the actual usage the model reports. It can differ from the estimate: any unused part of the hold returns to your balance, and usage above the hold is charged too, from your available balance. There is no cap, so `price.charged` can be above the hold.
4. **Released.** A task that fails, is canceled or is unresolved charges nothing and releases its hold. This includes tasks refused by content moderation.

| `billing_status` | Meaning |
| --- | --- |
| `pending` | Accepted; funding not done yet. |
| `unfunded` | The task closed before funding; nothing was held or charged. |
| `held` | Credits are held for the open task. |
| `settled` | The task is charged `price.charged`. |
| `released` | Nothing charged; the hold went back. |
| `refunded` | The charge was given back after the task settled: `price.charged` is `0.000` and `price.refunded` is the Credits returned. |

### Owed Credits

If a charge above the hold is more than your available balance, the rest is owed. [Get the balance](/docs/api/getWallet) shows it as `owed`, and `balance` (spendable Credits minus owed) goes below zero. While Credits are owed, new tasks are refused with HTTP 402 `balance_negative`; tasks already accepted still finish and settle. A top-up repays the owed Credits first, and only what is left becomes available.

## How the charge is measured

The hold is the estimate. When the task succeeds, the charge follows the actual usage the model reports, so it can be a little above or below the hold:

| Request | Held when accepted | Charged on success |
| --- | --- | --- |
| Seedance 2.5 and other Seedance models, any length | The rate × the seconds you ask for, or the longest length the tier allows for `duration: -1` | The tokens the model reports, at the tier's rate per second converted to tokens (input video included) |
| Wan and MiniMax video, with or without video input | The rate × the seconds you ask for (plus the input video's seconds when the tier counts them) | The output and input seconds the model reports billing, to the millisecond |
| Other video, set or auto length | The rate × the seconds you ask for, or the longest length the tier allows for `duration: -1` | The seconds delivered, to the millisecond |
| Images | The image price × the images you ask for, plus each input image beyond those the tier includes | The image price × the images delivered, never more than you asked for, plus the same input image charge |
| A result whose usage cannot be read | As above | The full hold |
| A result that arrives after the task closed | Nothing more | Nothing: a late result is free |

For example, a Seedream 5.0 Lite request for 4 images holds 4 × 7 = 28.000 Credits. If 3 images are delivered, `price.charged` is 21.000 and the other 7.000 Credits return to your balance.

### Seedance 2.5 edit

With `omni_reference_task_type: "edit"`, `duration` must be `-1`; any other value, or no `duration` at all, is refused with 422 `invalid_input` (rule `duration_must_be_auto`). The output runs as long as the source video, so the estimate shows `basis.auto: true` and the hold is:

| Part | Seconds held |
| --- | --- |
| Output | The measured length of the input videos together, rounded up, at most 30 |
| Input | The measured length of the input videos together, rounded down |
| Any input video not measured | 30 output and 30 input seconds |
| Billed | The larger of output + input and output × 5/3 rounded up |

The hold is billed seconds × the video tier's rate. The charge is the tokens the model reports, at the same rate, with no cap: `price.charged` can be above the hold. The part above the hold comes from your available balance, and what the balance cannot cover is owed, so new creates get 402 `balance_negative` until a top-up. See [Owed Credits](#owed-credits).

### Ledger entries for a task

Each step writes ledger entries whose `reference` starts with the step and ends with the task ID, and whose `task_id` names the task. The partial charge above writes:

| `reference` | `from` | `to` | `credits` |
| --- | --- | --- | --- |
| `hold:gen_…` | `available` | `held` | 28.000 |
| `settled:gen_…` | `held` | `consumed` | 21.000 |
| `settled-release:gen_…` | `held` | `available` | 7.000 |

A full charge writes only the `settled:` entry. A charge above the hold writes `settled:` for the whole hold, then `settled-extra:` (from `available` to `consumed`) for the part your balance paid and, if the balance ran out, `settled-owed:` (from `owed` to `consumed`) for the part owed.

A later top-up repays owed Credits with `repaid:` entries, from `available` to `owed`. A task that charges nothing writes `released:`, from `held` to `available`. A refund writes `reversed:`, from `consumed` to `available`. Refunding a charge above the hold returns all of it: the overage goes back to the Credits that paid it, and any owed part is cancelled with a `reversed:` entry from `consumed` to `owed`. When a hold draws on more than one batch of Credits, for example paid and bonus Credits, each step writes one entry per batch.

### Refunds

When a charged task is refunded, its `billing_status` becomes `refunded`, `price.charged` becomes `0.000` and `price.refunded` shows the Credits returned, which is what the task had been charged. `price.estimated` keeps the amount that was held.

## Reconcile

Read the balance with [get the balance](/docs/api/getWallet), using a project key with `balance:read` or a billing key, and every movement with [list ledger entries](/docs/api/listLedger), using a billing key with `billing:read`. Group entries by `task_id`. A settled task's `settled:`, `settled-extra:` and `settled-owed:` entries equal its `price.charged`; a refunded task's `reversed:` entries equal its `price.refunded`.

Packs are paid in US dollars. Amounts exclude tax unless stated otherwise.
