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

# 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`:

<CodeGroup>
  ```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),
  	}, "")
  ```
</CodeGroup>

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](/concepts/payment-protocols).

## 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](/integrate/settle-usage#report-usage) for work that finishes later.

<CodeGroup>
  ```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
  }
  ```
</CodeGroup>

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](/integrate/settle-usage) 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](/integrate/settle-usage#report-usage) for the reporting rules.
