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

# Words and billing

> How Wibble prices a request in API words, handles refunds, and how to buy more.

API words are the unit Wibble bills in for the public API. Each `POST /humanize` request reserves words from your API word balance based on the length of the input, and the rewritten output costs nothing extra. Words come from word packs you buy in the dashboard, never expire, and are separate from any subscription.

<Note>
  MCP connector jobs use normal Wibble words first, then purchased API words only as overflow. See [ChatGPT and Claude connectors](/guides/mcp-connectors).
</Note>

## How a request is priced

When you submit text, Wibble counts the words in your input and reserves that many words up front. The job object reports this in two fields:

* `words_reserved` — the words held for the request, equal to the input word count.
* `words_charged` — the net amount billed, equal to `words_reserved` minus any refunds, floored at `0`.

A request reserves words before the job runs. For a typical successful job, `words_charged` matches `words_reserved`:

```json theme={null}
{
  "id": "7b42f1d6-0a8c-4e8f-9a21-c6d9f47c2b10",
  "status": "succeeded",
  "input_words": 9,
  "words_reserved": 9,
  "words_charged": 9,
  "output": "Mitochondria are the cell's powerhouses."
}
```

<Note>
  Billing is based on the input word count, not the length of the output. The humanized text never adds to the charge.
</Note>

## Refunds

A failed job is fully refunded. Wibble releases the reserved words back to your balance and sets `words_charged` to `0`, so you are never billed for a job that does not produce output.

```json theme={null}
{
  "id": "7b42f1d6-0a8c-4e8f-9a21-c6d9f47c2b10",
  "status": "failed",
  "input_words": 9,
  "words_reserved": 9,
  "words_charged": 0,
  "error": {
    "code": "job_expired",
    "message": "The job expired before completion."
  }
}
```

This applies whether the job fails during processing, expires after about an hour, or is created but fails to enqueue. See [Errors](/concepts/errors) for the full list of failure codes.

## Insufficient balance

If your balance cannot cover a request, the submission is rejected with HTTP `402` and the `insufficient_words` error code before any job is created. The response body includes your current `balance` and the `words_required` for the request:

```json theme={null}
{
  "error": {
    "code": "insufficient_words",
    "message": "This request needs 9 API words, but the account only has 4 remaining."
  },
  "balance": 4,
  "words_required": 9
}
```

To recover, top up your balance with a word pack, then retry the request:

<Steps>
  <Step title="Buy a word pack">
    Add words to your account in the dashboard. See [Word packs](#word-packs) below.
  </Step>

  <Step title="Retry the submission">
    Resubmit the same request. With enough balance, Wibble reserves the words and returns a job with status `queued`.
  </Step>
</Steps>

<Tip>
  Compare `balance` against `words_required` to tell the user how many more words they need before retrying.
</Tip>

## Word packs

API words are sold in packs. Each pack is 100,000 words for \$25 USD. Words never expire and are separate from any subscription you may have, so a pack you buy stays on your balance until you use it.

<Card title="Buy words" icon="cart-shopping" href="https://www.wibbleai.com/dashboard/api">
  Purchase word packs from the API section of the Wibble dashboard.
</Card>

You buy packs in the dashboard, up to 20 packs per checkout. There is no per-pack discount; each pack is the same 100,000 words for \$25 USD.

## Check your balance

Your current word balance is shown in the dashboard, in the same API section where you buy packs and manage keys. Open [https://www.wibbleai.com/dashboard/api](https://www.wibbleai.com/dashboard/api) to view it.

## Next steps

<Columns cols={2}>
  <Card title="Errors" icon="triangle-exclamation" href="/concepts/errors">
    Every error code, including `insufficient_words`, and how to handle them.
  </Card>

  <Card title="Quickstart" icon="rocket" href="/quickstart">
    Go from an API key to your first humanized result.
  </Card>
</Columns>
