# ZeroGPU API errors and recovery through the agent storefront

Errors on ZeroGPU's agent storefront come from two layers, each with its own fix. The storefront answers credential, credit and purchase problems with a code in a top-level `error` string, which you fix by re-authenticating or by buying Credits from $0.01 on a wallet rail. ZeroGPU answers request problems with an `error` object once a call is forwarded, which you fix by changing the request.

## At a glance

- **Storefront errors:** JSON with the code as a string in `error`. Some carry a `reason`, a `hint` or a `detail` note. You recover by fixing the credential or buying Credits.
- **ZeroGPU errors:** after forwarding, `error` is an object with `message`, and sometimes `code` and `param`. You recover by fixing the request.
- **Endpoint:** `POST https://agents.zerogpu.ai/zcj/1hfs8qwwaown/zeroclick/v1/chat/completions` with `model` and `messages`. Send `Authorization: Bearer <token>`, the agent credential the storefront issues, or `Authorization: Receipt <receiptId>` from an anonymous credit.
- **How calls are paid:** calls draw on prepaid Credits. Only the purchase, `POST https://agents.zerogpu.ai/zcj/1hfs8qwwaown/plans/{planId}/purchase` with the plan id from [manifest.json](https://agents.zerogpu.ai/zcj/1hfs8qwwaown/manifest.json), returns a 402. A 402 is the price quote: you pay it once and retry. The minimum is $0.01 over x402 or MPP, the USDC wallet rails, and $0.50 by card.
- **Retry unchanged:** only `payment_provider_unavailable` and ZeroGPU's `500`, both with bounded backoff, and `429` after `retry-after`.
- **Reconcile before paying again:** after `payment_consumed`, `payment_refunded`, `payment_failed` or `payment_released`.
- **Full purchase flow:** [the buyer skill](https://agents.zerogpu.ai/zcj/1hfs8qwwaown/SKILL.md)

## Credential and receipt errors

### bearer_required (401)

The call or purchase carried no agent credential. This request sends a chat call with no credential:

```bash
curl -sS -X POST https://agents.zerogpu.ai/zcj/1hfs8qwwaown/zeroclick/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{"model": "LFM2.5-1.2B-Instruct", "messages": [{"role": "user", "content": "hello"}]}'
```

It returns `401` with this body, shown as an excerpt:

```json
{
  "error": "bearer_required",
  "hint": "This request needs an agent identity credential. Register once, exchange the assertion for a token, and retry with Authorization: Bearer <token> (or ZC-Agent-Authorization: Bearer <token> when Authorization carries your MPP Payment credential).",
  "auth": {"recipe": "https://agents.zerogpu.ai/zcj/1hfs8qwwaown/auth.md", "presentation": {"scheme": "Bearer", "standardHeader": "Authorization", "alternateHeader": "ZC-Agent-Authorization"}}
}
```

A Credits purchase above the anonymous credit amount, sent with no credential, returns the same code before any price is quoted.

To recover:

1. Reuse a ZeroClick credential you already hold. If you have none, register at [auth.md](https://agents.zerogpu.ai/zcj/1hfs8qwwaown/auth.md).
2. Exchange the stored assertion at `https://agents.zerogpu.ai/zcj/1hfs8qwwaown/oauth2/token` for an access token.
3. Retry with `Authorization: Bearer <token>`. On MPP, the `Authorization` header carries the payment, so send `ZC-Agent-Authorization: Bearer <token>` instead.

If you have no funded wallet and no card, send `checkout: true` with your bearer on the purchase. The storefront returns an unpaid hosted checkout page.

### invalid_token (401)

The agent credential did not verify. The `reason` field says why.

| `reason` | Action |
| --- | --- |
| `token_expired`, `token_invalid` | Trade your saved assertion for a new access token |
| `malformed_agent_authorization` | Send exactly one `Bearer <token>` in `ZC-Agent-Authorization` |
| `unrecognized_agent_credential` | Put only a ZeroClick-issued token in `ZC-Agent-Authorization` |
| `conflicting_agent_credentials` | Send one agent token, not two |
| `combined_authorization_unsupported` | Move the token from `Authorization` to `ZC-Agent-Authorization` |

If the exchange returns `invalid_grant`, refresh a claimed credential as [auth.md](https://agents.zerogpu.ai/zcj/1hfs8qwwaown/auth.md) describes. A `401` is not evidence that you have no purchase.

### identity_invalid

The proof of identity failed verification. Sign a new challenge and send it again.

### invalid_receipt (401)

The receipt is not one this seller can spend: malformed, still pending, revoked or issued elsewhere. This request sends a receipt that does not exist:

```bash
curl -sS -X POST https://agents.zerogpu.ai/zcj/1hfs8qwwaown/zeroclick/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Receipt rcp_doesnotexist' \
  -d '{"model": "LFM2.5-1.2B-Instruct", "messages": [{"role": "user", "content": "hello"}]}'
```

It returns `401` with `{"error":"invalid_receipt"}`. Send only the `receiptId` that a successful anonymous credit purchase returned. A payment id does not work as a receipt.

### receipt_credit_exhausted, receipt_credit_insufficient (402)

The receipt's balance cannot cover the call. These 402s are not a price quote, and receipts cannot be topped up. Buy another anonymous credit for a new receipt. For calls that need more, buy a larger Credits balance with a bearer credential.

## Plan and credit errors

### plan_required (403)

The credential holds no plan that covers the call. The body's `plans` lists the plans that do, each with its `purchase.url`. Buy Credits with your bearer, then retry the call.

### access_not_found

Recover the correct identity first. Then check what you already own with `GET https://agents.zerogpu.ai/zcj/1hfs8qwwaown/agent/entitlements` and your bearer before you buy again.

### usage_exhausted

Your Credits balance ran out. Top it up with `POST https://agents.zerogpu.ai/zcj/1hfs8qwwaown/extend`, your bearer and `amountUsd`. The new balance returns as `access.remainingCreditUsd`.

## Credits purchase errors

A Credits purchase takes `amountUsd` as a whole-cent string. With a bearer credential, the storefront returns one 402 for that amount.

| Code | Meaning | Action |
| --- | --- | --- |
| `invalid_request` (400) | The body is malformed | Fix the JSON |
| `amount_required` (400) | No `amountUsd` was sent | Include `amountUsd` |
| `amount_not_cent_increment` (400) | The amount includes a fraction of a cent | Round to whole cents |
| `amount_below_minimum` (400) | The amount is under `purchase.minimumUsd` | Send at least $0.01 |
| `amount_below_card_minimum` (400) | The amount clears the plan minimum but not the card minimum | Send at least $0.50 by card, or pay on x402 or MPP |
| `plan_not_found` (404) | The plan id is unknown | Take the id or `purchase.url` from [manifest.json](https://agents.zerogpu.ai/zcj/1hfs8qwwaown/manifest.json) |
| `seller_not_found` (404) | The host does not map to a seller | Use `https://agents.zerogpu.ai/zcj/1hfs8qwwaown` as the base URL |

A purchase whose `amountUsd` includes a fraction of a cent returns `400` with `{"error":"amount_not_cent_increment"}`.

## Payment errors on the purchase 402

| Code | Meaning | Action |
| --- | --- | --- |
| `settlement_failed` | The signed payment did not settle. `settlementReason` says why, for example `insufficient_funds`. | Fix the wallet, then send the purchase from the start for a fresh 402 |
| `payment_consumed` | The payment was already settled | Reconcile the original purchase before paying again |
| `payment_refunded`, `payment_failed`, `payment_released` | The payment reference is terminal | Check its status or receipt route. If no check exists, stop with an unknown outcome. |
| `payment_incomplete` | The payment has not finished | For a card payment, poll `statusUrl` until it is complete, then retry |
| `payment_unknown` | The reference matches no payment of yours here | Check the id, or start the purchase again to get a new 402 |
| `payment_provider_unavailable` | A transient failure reaching the payment provider | Retry unchanged, with backoff |

## Request errors

These errors need a change to the request, not to the credential. Once the storefront forwards a call, the response is ZeroGPU's own status and body.

A chat body that omits `model` returns `400` with `{"error":{"message":"Missing or invalid \"model\""}}`, even when the call carries no credential, since `model` is checked first.

An embedding model sent to chat completions returns `400` with `{"error":{"message":"Model not supported: all-minilm-l6-v2","param":"model","code":"model_not_found"}}`. `all-minilm-l6-v2` and `bge-small-en-v1.5` are embedding models and answer only on `/zeroclick/v1/embeddings`. Chat completions takes models such as `LFM2.5-1.2B-Instruct`:

```bash
curl -sS -X POST https://agents.zerogpu.ai/zcj/1hfs8qwwaown/zeroclick/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <token>' \
  -d '{"model": "LFM2.5-1.2B-Instruct", "messages": [{"role": "user", "content": "hello"}]}'
```

| Status | Body | Action |
| --- | --- | --- |
| `400` | `message` names the problem: invalid JSON, or a missing or invalid `model` or `messages` | Fix the body. Do not retry it unchanged. |
| `400` `model_not_found` | The endpoint does not route that `model` | Send the model to the endpoint that serves it |
| `420` `context_length_exceeded` | The input is over the model's token limit, with `param` set to `messages` | Shorten the input |
| `429` `requests_per_minute_exceeded` | A rate limit was reached. Limits are counted per agent. | Wait at least `retry-after` seconds, then retry |
| `500` `internal_error` | An unexpected server error | Retry with bounded backoff |

## Frequently asked questions

### What is the difference between bearer_required and plan_required?

`bearer_required` means the request carried no agent credential, so you register or reuse one and retry. `plan_required` means the credential is valid but holds no plan that covers the call. Buy Credits with that bearer at `POST https://agents.zerogpu.ai/zcj/1hfs8qwwaown/plans/{planId}/purchase`, then retry the call.

### Why does a chat call return Missing or invalid model?

The body has no `model` field, or its value is not a model id. The storefront checks `model` before the credential, so this error appears even on a call with no credential. Set `model` to a model id the endpoint serves, such as `LFM2.5-1.2B-Instruct`, and send the call again.

### Does a ZeroGPU call answer with a 402 price quote?

No. Calls draw on prepaid Credits or on a receipt's credit. Only the Credits purchase returns a priced 402, starting at $0.01 on a wallet rail and $0.50 by card. A 402 on a call with a receipt means the receipt's credit cannot cover it.

### Which errors can I retry unchanged?

You can retry `payment_provider_unavailable` and ZeroGPU's `500` with bounded backoff, and `429` after the `retry-after` wait. Every other code needs a new credential, a purchase, a changed request or a reconciliation first.

### What does amount_not_cent_increment mean?

The `amountUsd` on a Credits purchase includes a fraction of a cent. Round it to whole cents, keep it at or above the minimum, and send the purchase again.

## Keep reading

- [The buyer skill](https://agents.zerogpu.ai/zcj/1hfs8qwwaown/SKILL.md): the full purchase and recovery flow
- [Error reference](https://agents.zerogpu.ai/zcj/1hfs8qwwaown/errors.md): every storefront code
- [Agent identity](https://agents.zerogpu.ai/zcj/1hfs8qwwaown/auth.md): register, exchange and refresh a credential
- [How to pay](https://agents.zerogpu.ai/zcj/1hfs8qwwaown/payment.md): the purchase 402 and each rail
- [Catalog](https://agents.zerogpu.ai/zcj/1hfs8qwwaown/manifest.json): plans, purchase URLs and live prices

---

Updated 2026-10-14. All ZeroGPU guides: https://agents.zerogpu.ai/guides.md. Storefront: https://agents.zerogpu.ai/zcj/1hfs8qwwaown/llms.txt.
