# Dappier error reference

Errors are JSON with the code in the top-level `error` field, sometimes refined by a `reason` (on a `payment_required`) or carrying a human `detail` note. The common cases:

## Payment and access

- `bearer_required` (401): this call needs a registered agent credential, which a wallet cannot supply. Follow https://agents.dappier.com/zcj/grahqhuwea6i/auth.md to register, then retry with `Authorization: Bearer <token>` (or `ZC-Agent-Authorization: Bearer <token>` when `Authorization` carries an MPP `Payment` credential).
- `invalid_token` (401): the agent credential did not verify; `reason` says why. `token_expired` / `token_invalid`: re-exchange your stored assertion for a fresh token. `malformed_agent_authorization`: `ZC-Agent-Authorization` must be exactly one `Bearer <token>`. `unrecognized_agent_credential`: that header carried something other than a ZeroClick-issued token (seller and payment credentials stay in `Authorization`). `conflicting_agent_credentials`: `Authorization` and `ZC-Agent-Authorization` carried two different agent tokens - send one. `combined_authorization_unsupported`: `Authorization` held a comma-combined `Payment ..., Bearer ...` value; it carries one credential - move the token to `ZC-Agent-Authorization`.
- `entitlements_not_available` (501): this storefront does not sell plans or top-ups.
- `identity_invalid`: the identity proof did not verify. Sign a fresh challenge and retry.
- `access_not_found`: you have no active plan to draw from or extend. Buy a plan first with `POST /plans/{planId}/purchase`.
- `usage_exhausted`: your plan's credit ran out. Top up with `POST /extend` or purchase again.
- `settlement_failed`: your signed payment did not settle; `settlementReason` says why (e.g. `insufficient_funds`). Fix your wallet and retry the request from the start for a fresh challenge.
- `payment_refunded` / `payment_consumed` / `payment_failed` / `payment_released`: TERMINAL. The payment you referenced was refunded, already spent on a previous request, failed, or (for a card) released without any charge - it will never become spendable again, so retrying the same reference is guaranteed to fail forever. If you still need the resource, start over: make a fresh unpaid request, receive a new 402, and pay that one.
- `payment_incomplete`: the payment you referenced has not finished. Complete it first (for card payments, poll the `statusUrl` from the 402's `card` block until it reports complete), then retry.
- `payment_unknown`: the reference does not match a payment available to you at this seller. Check the id; if it came from a stale challenge, make a fresh request for a new 402.
- `payment_provider_unavailable`: a transient failure reaching the payment provider - the only payment error worth retrying unchanged, with backoff.
- no `reason` (a `payment` block is present): the normal per-call charge. Settle it via the challenge and retry with the proof attached.

## Bad request (`400`)

- `invalid_request`: the request body is malformed. Fix the JSON.
- `payg_not_purchasable`: you tried to buy a pay-as-you-go plan. Do not purchase payg; just call the API.
- `amount_required`: buying a credit plan without an amount. Include `{ "amountUsd": "25.000000" }`.
- `amount_not_cent_increment`: the `amountUsd` was not a whole-cent value. Round to whole cents.
- `amount_below_minimum`: the `amountUsd` was under the plan's `purchase.minimumUsd`. Send at least that minimum.
- `amount_below_card_minimum`: the `amountUsd` cleared the plan's own minimum but not the card rail's $0.50 floor (`purchase.cardMinimumUsd`). Raise the amount to it, or settle the smaller amount on a wallet rail, which is not subject to this floor.

## Not found (`404`)

- `seller_not_found`: this host does not map to a seller. Check the base URL.
- `plan_not_found`: unknown plan id. Use an id from `GET https://agents.dappier.com/zcj/grahqhuwea6i/manifest.json`.

## Seller or configuration issues (`409`, not caused by your request)

Retry later or contact the seller.

- `signing_secret_required`: the seller has not finished setup.
- `payment_request_mismatch`: a payment was reused for a different request. Request a fresh 402 and settle that one; do not reuse a payment across requests.
- `payment_amount_mismatch`: a purchase or extend retry carried a different `amountUsd` than the challenge you paid. Retry with the amount the 402 quoted.
- `usage_not_priced`: the upstream reported usage at a rate ZeroClick has no price for, so the call could not be billed.

Once a paid call is proxied, you receive the upstream API's own status code and body, including its own errors.

Not every problem is a JSON error body. If ZeroClick cannot bill a usage report from an otherwise successful upstream response, it still returns the upstream's own body and status and notes the billing problem in a `zc-usage-error` response header (for example `invalid_usage_header`). You were served the response, so do not retry.

