# Billing

## Credits

Amounts are in credits. Credits are written as JSON numbers with up to 6 decimals; the smallest unit is a micro-credit, so amounts are exact.

The account balance is prepaid. Each call is priced from the price list, and failed calls cost 0.

| Field | Meaning |
|---|---|
| `cost` | What this call charged, in credits. |
| `balance` | The account balance after this call. |

## Price list

| Model | Unit | Billed item and when it is charged | Price (credits) |
|---|---|---|---|
| `sam3` | `encode_image` | Image encoding, per image: once per call; waived while the encoding of the same image is still cached for the account | 0.5 |
| `sam3` | `prompt` | Text prompt: one decode per text phrase in `POST /v1/segment`; exemplar boxes, positive or negative, add no charge, and a call with boxes and no text phrase is one `prompt` | 0.05 |
| `sam3` | `point` | Point prompt: one decode per point in `POST /v1/segment` | 0.02 |
| `sam3` | `refine` | Refinement: one decode per `POST /v1/refine` call, whatever the number of points and whether a box is given | 0.02 |
| `sam-lite` | `encode_image` | Image encoding, per image: as for `sam3` | 0.2 |
| `sam-lite` | `point` | Point prompt: one decode per point in `POST /v1/segment` | 0.01 |
| `sam-lite` | `box` | Box prompt: one decode per box in `POST /v1/segment` | 0.01 |
| `sam-lite` | `refine` | Refinement: one decode per `POST /v1/refine` call, as for `sam3` | 0.01 |
| `ppocr-v6` | `image` | Text recognition: one image per request | 0.25 |
| `paddleocr-vl` | `page` | Document parsing: one page image per request | 2 |
| `dinov3` | `image` | Image embedding: one image per request | 0.05 |
| `siglip2` | `image` | Image embedding: one image per request | 0.05 |
| `siglip2` | `text` | Text embedding: each string in `texts[]` | 0.01 |
| `birefnet` | `image` | Background removal: one image per request | 1 |

Notes on the units:

- `ppocr-v6`: one `image` per call, whatever the number of lines or words and whether `options.words` is on.
- `paddleocr-vl`: one `page` per call, whatever the number of blocks.
- `siglip2`: a text search over N stored images costs N `image` units once, then one `text` per query.
- `birefnet`: the cutout and the matte cost the same; there is no cache discount, every call runs the full model.

`GET /v1/models` returns the current prices in `prices[]` with the same units. Prices are versioned; every call is priced with the version in force when it ran.

## Reserve and settle

A call reserves its full price before it runs and settles on what the worker reports. Failed calls release the reservation and are not charged. A balance that cannot cover the reservation answers `402 insufficient_balance`.

## SAM image encoding fee and cache hits

`sam3` and `sam-lite` charge an image encoding fee (`encode_image`) per call. When the encoding of the same image was already computed for the account and is still cached on the GPU node, the fee is waived. The response then says `"cache": "hit"` with `"imageFee": 0`, and the `encode_image` line has `waived: true` and `amount: 0`.

```json
{
  "cache": "hit",
  "imageFee": 0,
  "billing": {
    "lines": [
      { "unit": "encode_image", "quantity": 1, "unitPrice": 0.5, "amount": 0, "waived": true },
      { "unit": "refine", "quantity": 1, "unitPrice": 0.02, "amount": 0.02, "waived": false }
    ],
    "total": 0.02,
    "charged": true,
    "pool": null
  }
}
```

A cache hit is a bonus, not a promise. Cached encodings are deleted after at most 7 days and are evicted earlier when capacity is needed, so there is no minimum retention. Pricing for planning purposes must assume the encoding fee on every call. Caches are per account and are never shared across accounts.

Refining an image that was just segmented is often a cache hit, but the fee is only waived when the response says so.

## How SAM calls are billed

SAM calls are billed by the number of decodes. A decode is one pass of the model for one prompt or one object, run on the image encoding. The image encoding itself (`encode_image`) is billed once per call and is waived on a cache hit. How the stages work is described under [How it works](https://stack.foldbun.com/docs/models/sam3/#how-it-works) on the model pages.

| Endpoint | One decode is | Unit |
|---|---|---|
| `POST /v1/segment` | Each prompt | `sam3`: `prompt` for each text prompt (exemplar boxes, positive or negative, add no charge; a box-only call is one `prompt`), `point` for each point. `sam-lite`: `point` for each point, `box` for each box. |
| `POST /v1/refine` | The whole call, whatever the number of points and whether a box is given | `refine` |

Worked examples at list prices:

- `sam3`, `POST /v1/segment`, 3 text prompts on a new image: 0.5 (`encode_image`) + 3 × 0.05 (`prompt`) = 0.65 credits.
- `sam3`, `POST /v1/segment`, 2 text prompts and 3 exemplar boxes on a new image: 0.5 + 2 × 0.05 = 0.60 credits, because the boxes add no charge.
- `sam3`, `POST /v1/segment`, 4 exemplar boxes and no text prompt on a new image: 0.5 + 0.05 = 0.55 credits, one `prompt` for the single visual query.
- `sam3`, `POST /v1/segment`, 1 text prompt and 2 points on a new image: 0.5 + 0.05 + 2 × 0.02 = 0.59 credits.
- `sam-lite`, `POST /v1/segment`, 4 boxes on a new image: 0.2 + 4 × 0.01 = 0.24 credits.
- `sam3`, `POST /v1/refine`, 10 clicks on a cached image, each click sent as its own call with all earlier clicks: 10 × 0.02 = 0.20 credits, because the encoding is waived. The first call on a new image costs 0.5 + 0.02. With `sam-lite` the same editing session costs 0.2 + 0.01 for the first call and 0.01 for each later one.
- A single `POST /v1/refine` call with 12 points and a box is still one `refine`: 0.02 with `sam3`, plus the encoding when it is not cached.

Pools can cover a call without charging the balance; the `billing` lines still show these list prices. The unit prices above are the current ones, and every call is priced with the version in force when it ran.

## The `billing` object

Every successful inference response carries `billing`, which explains how the call was priced.

| Field | Meaning |
|---|---|
| `lines[]` | One line per priced unit: `unit`, `quantity`, `unitPrice`, `amount` and `waived`. |
| `total` | The sum of the lines. When the balance could not cover the whole price, `total` is what was actually debited. |
| `charged` | Whether the balance was debited. `false` for calls covered by an included daily allowance and for Playground trial calls. |
| `pool` | The pool whose daily allowance covered the call (`public` or `free`). `null` for billed calls. |
| `allowance` | `used` and `limit` of today's (UTC) included calls, counting this one. Present only when `pool` is set. |
| `capped` | Present and `true` only when the price exceeded the balance and the debit was cut down to it. |

`cost` always agrees with `billing`: it equals `total` when `charged` is `true`, and 0 otherwise. On a call that is not charged, the lines still show the list price.

Example of a billed `sam3` call with two text prompts and a cache miss:

```json
{
  "cost": 0.6,
  "balance": 998.4,
  "cache": "miss",
  "imageFee": 0.5,
  "billing": {
    "lines": [
      { "unit": "encode_image", "quantity": 1, "unitPrice": 0.5, "amount": 0.5, "waived": false },
      { "unit": "prompt", "quantity": 2, "unitPrice": 0.05, "amount": 0.1, "waived": false }
    ],
    "total": 0.6,
    "charged": true,
    "pool": null
  }
}
```

## Adding credit

- The minimum top-up is US$0.99 (990 credits).
- Top-ups are credited at US$1 = 1,000 credits.
- Credits do not expire.
- The first top-up also unlocks the free and paid pools. See [Rate limits and pools](https://stack.foldbun.com/docs/rate-limits/).

Online top-up is not available yet. The **Billing** page of the [console](https://stack.foldbun.com/console/billing) explains how to add funds.
