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

# Usage and allowances

> What an allowance check decides, the three usage-item forms, the seven denial reasons, free mode, and how sync and async settlement stay idempotent.

An allowance is the answer to one question, asked before billable work runs: does this buyer's plan cover this usage? Your API asks it with `POST https://api.zeroclick.io/v1/usage/check` (API key scope `usage:read`). The body carries the request's `zcRequestId`, the `serviceSlug`, and 1 to 20 usage items: one per meter, no duplicates. The response is a pure decision:

```json Request theme={null}
{
  "zcRequestId": "zcreq_8h2m4x0q9k1f",
  "serviceSlug": "product-watch",
  "usage": [{ "meterSlug": "output_tokens", "maxQuantity": 8192 }]
}
```

```json Response theme={null}
{ "allowed": true, "reason": null }
```

A check records nothing and burns nothing: no usage event, no credit deduction, no included units consumed. It exists so you can refuse before doing the work; billing happens only when you settle. The [check allowances](/integrate/check-allowances) guide covers calling it; this page covers what the answers mean.

## The three usage-item forms

Each usage item names a meter and sizes the usage one of three ways. An item may not declare both a quantity and a ceiling.

* `quantity`: the exact amount, known up front ("this call is 1 request").
* `maxQuantity`: a ceiling for work you cannot size in advance ("at most 8,192 output tokens"). The check gates at the ceiling: could the largest allowed call go through?
* Neither: the item falls back to the meter's `defaultMaxQuantity` from the [plan meter price](/concepts/plans-and-pricing) and gates at that ceiling. If the meter has no default, there is nothing to gate against, and the check denies `meter_not_priced`.

Quantities are integers from 1 to 2,147,483,647.

## The seven denial reasons

`allowed: false` always comes with exactly one machine-readable reason:

| Reason              | Meaning                                                                                                                                                           |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `service_not_found` | The `serviceSlug` does not name a service in your catalog.                                                                                                        |
| `access_not_found`  | Nothing stands behind the request: no active access, no verified payment, no free-mode coverage. This is the normal first-touch denial that becomes a priced 402. |
| `access_inactive`   | The buyer's access exists but is not active, or its period has not started.                                                                                       |
| `plan_expired`      | The access period has ended (`periodEndsAt` is in the past).                                                                                                      |
| `meter_not_found`   | The `meterSlug` does not name a meter on this service.                                                                                                            |
| `meter_not_priced`  | The buyer's plan has no price for this meter, or the item declared neither quantity nor ceiling and the meter has no `defaultMaxQuantity`.                        |
| `usage_exhausted`   | The plan prices the usage, but the remaining balance or allowance cannot cover the declared amount.                                                               |

Your API turns a denial into the `402 payment_required` refusal body, and ZeroClick re-prices it into the buyer's next challenge. A denial is a payment prompt, not a dead end. The [errors reference](/resources/errors) lists the response shapes.

## Free mode

Prices can carry `includedUnits`: free units per period before the price applies. On pay-as-you-go, consuming them is an explicit opt-in: the agent sends the `zc-mode: free` request header on each call. A missing or unrecognized header means paid; ZeroClick never rejects a call over it. Anonymous free-mode calls are never served free, and neither are unclaimed agents: the allowance is reserved for agent identities claimed by a human with a verified email, and it is scoped to that buyer - consumption aggregates across every agent the same human owns, so claiming more agents never grants more free usage. ZeroClick answers anonymous calls with a \$0 identity challenge first, and the identified retry gets the real coverage check, including the claimed-and-verified requirement. ZeroClick records the mode on the request, so your allowance check and the usage recorder honor the same decision ZeroClick made. See [free and identity endpoints](/integrate/free-and-identity-endpoints).

## Settling usage: sync and async

A check gates; a settlement records. There are two ways to settle, and both write the same usage events:

* **Sync (preferred):** put a `zc-usage` header on your 2xx response. ZeroClick records it while returning the response and strips the header before the agent sees it. A request can never settle the same meter twice.

  ```http theme={null}
  zc-usage: [{"serviceSlug":"product-watch","meterSlug":"output_tokens","quantity":4523}]
  ```

* **Async:** call `POST https://api.zeroclick.io/v1/usage` (scope `usage:write`) with `zcAgentId`, `serviceSlug`, `meterSlug`, `quantity`, an optional `occurredAt`, and an `idempotencyKey`. Async events are unique per `(service, idempotencyKey)`. Keys are yours and must be derived, never random (`zcreq_8h2m4x0q9k1f_output_tokens`), so a retry reproduces the same key. A replay answers `"recorded": true, "duplicate": true` with the originally stored event: a success, not an error.

Every recorded usage event carries `source: "sync"` or `"async"`, along with the `zcAgentId`, `zcRequestId`, `meterSlug`, `quantity`, and the computed `totalCostUsd`. This is the same record you see in the dashboard and the [REST API](/api-reference/introduction). ZeroClick can also refuse a report after the fact: `402` for `access_inactive`, `plan_expired`, or `usage_exhausted`, `409` for `meter_not_priced`, and `404` otherwise. That is one more reason to check before you serve. The [settle usage](/integrate/settle-usage) guide covers both paths in code.
