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

# Charge up to a maximum

> Bill work you can't size up front (output tokens, pages, seconds of processing) by declaring a ceiling and settling at the actual amount used.

You can't price some work until it is done: tokens generated, pages extracted, seconds of processing. Charging a flat worst-case rate overcharges everyone else; metering after the fact leaves the buyer unauthorized. ZeroClick's answer is a ceiling: declare the most the request could use, let the buyer authorize that maximum, and settle at what the request actually used.

## Charging up to a maximum

Declare the ceiling with `maxQuantity` instead of `quantity`:

```ts TypeScript theme={null}
const decision = await zeroClick.guard(request, {
  serviceSlug: "product-watch",
  usage: [
    { meterSlug: "requests", quantity: 1 },
    { meterSlug: "output_tokens", maxQuantity: 100_000 },
  ],
});
```

```python Python theme={null}
decision = await zeroclick.guard(
    zc_request,
    service_slug="product-watch",
    usage=[
        UsageItem(meter_slug="requests", quantity=1),
        UsageItem(meter_slug="output_tokens", max_quantity=100_000),
    ],
)
```

```go Go theme={null}
result, err := seller.Guard(r.Context(), sellers.FromHTTP(r, body), "product-watch",
	[]sellers.UsageItem{
		sellers.PerRequest("requests", 1),
		sellers.UpTo("output_tokens", 100_000),
	}, "")
```

The buyer authorizes up to the ceiling, and the payment settles at the actual usage you report: a ceiling never overcharges. The SDK rejects a usage item that declares both `quantity` and `maxQuantity` before any network call.

You can also declare **neither**: the item then defers to the meter's configured **Max usage per request** (`defaultMaxQuantity` on the plan's meter price). That keeps the ceiling in your catalog instead of your code. If the meter has no configured maximum, the allowance check denies with `meter_not_priced`.

On the buyer's side, a ceiling is payable only on the reserve payment rails: the agent authorizes the maximum and pays the actual amount you settle. An exact `quantity` lets ZeroClick offer the immediate-settle scheme more clients can pay today, so when you know the size, prefer fixed charges. See [payment protocols](/docs/concepts/payment-protocols.md).

## Settle at the actual amount

A ceiling has no settled quantity until you report one. Settle it like any other usage: on the response for amounts you know by the end of the handler, or [asynchronously](/docs/integrate/settle-usage.md#report-usage) for work that finishes later.

```ts TypeScript theme={null}
// 4,200 tokens actually produced, against the 100,000 ceiling.
return zeroClick.withUsage(response, [
  { serviceSlug: "product-watch", meterSlug: "requests", quantity: 1 },
  { serviceSlug: "product-watch", meterSlug: "output_tokens", quantity: 4200 },
]);
```

```python Python theme={null}
return to_fastapi(
    zeroclick.with_usage(
        ZcResponse.json({"tokens": 4200}),
        [
            SyncUsageItem(service_slug="product-watch", meter_slug="requests", quantity=1),
            SyncUsageItem(service_slug="product-watch", meter_slug="output_tokens", quantity=4200),
        ],
    )
)
```

```go Go theme={null}
value, err := sellers.UsageHeader([]sellers.SyncUsageItem{
	{ServiceSlug: "product-watch", MeterSlug: "requests", Quantity: 1},
	{ServiceSlug: "product-watch", MeterSlug: "output_tokens", Quantity: 4200},
})
if err == nil {
	w.Header().Set("zc-usage", value) // before writing the body; 2xx only
}
```

The settled quantity can be anywhere from zero up to the declared ceiling. An unreported ceiling on a paid, delivered response settles at zero (safe for the buyer, unbilled for you), so the report is what turns the work into revenue. See [settle usage](/docs/integrate/settle-usage.md) for the header rules (2xx only, stripped by ZeroClick).

## Go: Meter takes fixed quantities only

Go's `Meter` middleware settles exactly what it declares, so it accepts fixed quantities only. Handed an `UpTo` item, it **panics at wire-up**: a ceiling has no settled quantity, and the middleware would otherwise bill zero, silently, on a delivered 200. You have two working shapes: call `Guard` yourself and settle explicitly, or keep `Meter` for a fixed per-request charge and report the variable part after responding.

```go theme={null}
mux.Handle("/v1/product-watch", seller.Meter(sellers.PerRequest("requests", 1))(
	http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		zc, _ := sellers.FromContext(r.Context())

		tokens := doTheWork() // discovered by doing the work

		w.Header().Set("content-type", "application/json")
		fmt.Fprintf(w, `{"tokens":%d}`, tokens)

		// Reported after the response, on BackgroundContext (r.Context() is
		// already cancelled) with a derived idempotency key.
		_, err := seller.ReportUsage(sellers.BackgroundContext(r), sellers.ReportUsageInput{
			AgentID:        zc.AgentID,
			ServiceSlug:    "product-watch",
			MeterSlug:      "output_tokens",
			Quantity:       tokens,
			IdempotencyKey: zc.RequestID + "_output_tokens",
		})
		if err != nil {
			log.Printf("output_tokens not reported: %v", err)
		}
	})))
```

The fixed charge keeps the immediate-settle scheme available to buyers; the report settles the variable part. The same fixed-plus-reported split works in any language when you know the variable amount only after the response. See [settle usage](/docs/integrate/settle-usage.md#report-usage) for the reporting rules.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.