> ## 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.

# Introduction

> Overview of the Wibble HTTP API: base URL, authentication, the job model, limits, and errors.

The Wibble API humanizes text. You submit text to a single endpoint, Wibble processes it asynchronously, and you retrieve the rewritten result by polling or by receiving a webhook. This page is the API overview; each topic links to a core concept page that covers it in depth.

All requests go to the production base URL:

```bash theme={null}
https://www.wibbleai.com/api/v1
```

## Authentication

Every request requires a Bearer API key in the `Authorization` header:

```bash theme={null}
Authorization: Bearer wib_live_...
```

Keys are created in the Wibble dashboard and look like `wib_live_...`. A key must carry the `humanize` scope to call these endpoints. Requests with a missing or invalid key return `401 unauthorized`.

<Warning>
  Treat API keys as secrets. The v1 API is designed for server-to-server use; use keys only from server-side code, never from a browser or mobile client. Anyone with the key can spend your account's API words.
</Warning>

## Jobs

Humanization is asynchronous. `POST /humanize` reserves API words and returns a job with status `queued` (HTTP `202`). You then track the job by polling `GET /humanize/{id}` or by receiving a webhook. A job moves through four statuses; `succeeded` and `failed` are terminal.

| Status      | Meaning                                         |
| ----------- | ----------------------------------------------- |
| `queued`    | Accepted and waiting to start.                  |
| `running`   | Being processed.                                |
| `succeeded` | Finished. `output` contains the humanized text. |
| `failed`    | Did not finish. Reserved words were refunded.   |

For the full job object, the difference between polling and webhooks, and the recommended poll interval, see [Jobs](/concepts/jobs).

## Words and billing

Each job reserves API words up front based on its input word count, and `words_charged` is the net amount billed after any refund. A failed job is charged `0`. A `402 insufficient_words` response means the account balance cannot cover the request. See [Words and billing](/concepts/words-and-billing) for packs, refunds, and how to buy words.

## Limits

| Limit                     | Value                                         |
| ------------------------- | --------------------------------------------- |
| Input text                | 50,000 characters and 2,000 words per request |
| Request body              | 128,000 bytes                                 |
| Concurrent jobs           | 5 active jobs per account                     |
| Submission rate (`POST`)  | 20 requests per minute per key                |
| Lookup rate (`GET`)       | 120 requests per minute per key               |
| Idempotency key retention | 24 hours                                      |

Rate-limited responses (`429`) include a `Retry-After` header along with `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` headers describing the current window.

## Idempotency

Send an `Idempotency-Key` header to make a submission safe to retry. Reusing a key with an identical body returns the original job, and reusing it with a different body within the retention window returns `409 idempotency_conflict`. See [Idempotency](/concepts/idempotency) for the retry pattern and conflict handling.

## Errors

Errors use a consistent envelope with a machine-readable `code` and a human-readable `message`:

```json theme={null}
{
  "error": {
    "code": "validation_error",
    "message": "Text is required"
  }
}
```

Some errors add fields to the envelope — for example, `402 insufficient_words` includes `balance` and `words_required`. See [Errors](/concepts/errors) for the full list of codes and how to handle each one.

## Webhooks

Set `webhook_url` on a submission to receive a signed `POST` when the job reaches a terminal state. Wibble sends [`humanize.job.succeeded`](/api-reference/webhooks/job-succeeded) and [`humanize.job.failed`](/api-reference/webhooks/job-failed) events, each attempted up to 3 times with exponential backoff. Verify every delivery before trusting it. See [Webhooks](/concepts/webhooks) for the payload, signature verification, and delivery details.

## Next steps

<Columns cols={2}>
  <Card title="Quickstart" icon="rocket" href="/quickstart">
    Submit your first job and read the result end to end.
  </Card>

  <Card title="Submit a job" icon="paper-plane" href="/api-reference/humanize/submit">
    Reference for `POST /humanize`, including every request option and response.
  </Card>

  <Card title="Retrieve a job" icon="magnifying-glass" href="/api-reference/humanize/retrieve">
    Reference for `GET /humanize/{id}` and the job object.
  </Card>

  <Card title="Webhooks" icon="bell" href="/concepts/webhooks">
    Verify deliveries and handle job events reliably.
  </Card>
</Columns>
