> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zerogen.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Billing

> Read money fields, how a generation is held and charged, and your organization's balance.

Generations from live keys are billed to your organization's balance, which
every member and project shares. ZeroGen reports what it holds before the work
and what it charges after.

## Money fields

Every amount is an integer number of micro-USD, in a field whose name ends in
`MicroUsd`. One US dollar is 1,000,000 micro-USD, so `42000` is USD 0.042.
Integers keep amounts exact; convert to dollars only for display.

## A generation's billing

Every generation has a `billing` object:

```json theme={null}
{
  "mode": "platform",
  "state": "held",
  "hold": {
    "state": "running",
    "endedAt": null
  },
  "quotedMicroUsd": 42000,
  "heldMicroUsd": 42000,
  "chargedMicroUsd": null
}
```

| Field | Description |
| - | - |
| `mode` | Who pays. `platform`: ZeroGen bills your organization. `byok`: the generation runs on your organization's own provider key, so the provider bills you and ZeroGen charges nothing. `test`: a [test key](https://docs.zerogen.com/test-keys.md) ran it, and nothing is charged. |
| `state` | `held`, `charged`, `released`, or `null`. |
| `hold` | Present only while `state` is `held`. |
| `quotedMicroUsd` | The quote: the maximum expected charge, which ZeroGen held when the generation started. |
| `heldMicroUsd` | While `held`, the amount held now. Otherwise `null`. A held amount is never a charge. |
| `chargedMicroUsd` | The final charge once `charged`, and `0` once `released`. Otherwise `null`. |

### Billing states

| `state` | Meaning |
| - | - |
| `held` | An amount is held and nothing is charged yet. |
| `charged` | `chargedMicroUsd` is the final charge. |
| `released` | The hold ended with no charge. |
| `null` | Billing never admitted the generation, for example because it was refused, so nothing was held or charged. `quotedMicroUsd` is also `null`. |

While a generation is `held`, `hold.state` reports where it stands. It reports
facts, not a prediction of the charge:

| `hold.state` | Meaning |
| - | - |
| `running` | The generation hasn't ended. |
| `ended` | The generation ended, and the hold is still pending. `hold.endedAt` is when it ended. |
| `needs_attention` | The hold has stayed pending 30 minutes after the generation ended, or 24 hours after it started with no end recorded, so ZeroGen is looking into it. |

For a `byok` generation, `quotedMicroUsd` is `0`, `heldMicroUsd` is `0` while
held, and `chargedMicroUsd` is `0` once charged.

### What's charged

* The charge follows the work the provider actually reports, so it can differ
  from the quote. In rare cases, it can be higher than the quote.
* A failed output isn't charged for its output, but a generation is still
  charged for billable work that actually happened, such as accepting the
  request.
* Cancelling stops unfinished outputs. Outputs that a provider already finished
  are kept and charged.

## Check the cost before you start

To see a cost before you start, request a quote with
`POST /v1/generations/quote`. It holds nothing. For details, see
[Models](https://docs.zerogen.com/models.md#quote-a-generation).

To cap a create, send `maxCostMicroUsd`. If the quote is higher, the create
fails with `402 cost_limit_exceeded` and starts nothing. `maxCostMicroUsd` caps
the quote, not the final charge.

A create can also fail before it starts with these errors:

| Status | Code | Cause |
| - | - | - |
| `402` | `insufficient_balance` | The available balance can't cover the quote. |
| `402` | `spend_limit_reached` | The generation would pass the organization's monthly spend limit or the project's monthly budget. |
| `409` | `invalid_state` | The generation runs on your organization's own provider key and has no provider list price, so only a person can start it, in ZeroGen. |

## Read your balance

`GET /v1/balance` returns your organization's funds. It needs the
`account:read` scope. Add `projectId` to include that project's monthly budget.

```bash theme={null}
curl "https://api.zerogen.com/v1/balance?projectId=5a4b3c2d-1e0f-4a9b-8c7d-6e5f4a3b2c1d" \
  -H "Authorization: Bearer $ZEROGEN_API_KEY"
```

```json theme={null}
{
  "currency": "USD",
  "balanceMicroUsd": 250000000,
  "heldMicroUsd": 42000,
  "availableMicroUsd": 249958000,
  "unlimited": false,
  "limits": {
    "organizationMonthly": {
      "limitMicroUsd": 1000000000,
      "spentMicroUsd": 81250000,
      "enforced": true
    },
    "projectMonthly": {
      "limitMicroUsd": 200000000,
      "spentMicroUsd": 12500000
    }
  }
}
```

| Field | Description |
| - | - |
| `balanceMicroUsd` | The organization's balance. It can be negative. |
| `heldMicroUsd` | The amount held for generations that haven't settled. A hold isn't a charge. |
| `availableMicroUsd` | What a new generation's quote must fit within. It can be negative. |
| `unlimited` | When `true`, ZeroGen skips the funds check. Usage is still charged. |
| `limits.organizationMonthly` | The organization's monthly spend limit, with this UTC month's spend, or `null` when there's none. |
| `limits.projectMonthly` | With `projectId`, that project's monthly budget and this UTC month's spend. Otherwise `null`. |

A limit's `limitMicroUsd` can be `null`. If your organization's balance isn't
available, the response is `503 unavailable`.

The balance is a point-in-time read. A generation's quote and admission decide
whether it can start.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.