Skip to main content

Meter

Post-paid metered pricing on a Gate paywall. The buyer signs a spending ceiling once, your upstream reports the actual work in a response header, and the difference is refunded on-chain automatically.

3 min read
View MarkdownEdit on GitHub

Meter

Beta

Meter is merged and in beta while final mainnet validation completes. Gate's flat, tiered, and dynamic pricing models are live. Build against Meter now, but treat the metered lane as beta until validation closes.

Some calls cost you more than others. A short completion and a long one are not the same work, and pricing both at the same flat rate means you either overcharge the cheap call or eat the expensive one.

Meter prices a Gate paywall after the call instead of before it. The buyer authorizes a ceiling up front, your upstream reports what the request actually cost, and Meter refunds the difference on-chain. Set pricing_model: "metered" on the paywall to turn it on.

The flow

agent ──GET──▶ gw.codespar.dev/<slug> ──▶ 402 advertising the CEILING
      ◀──────────────────────────────────────┘
agent ──GET + signed ceiling──▶ gw.codespar.dev/<slug>
                                │ settle the ceiling on Base
                                │ proxy to your upstream
                                │ read the units header off the response
                                │ actual = base × multiplier
                                │ refund (ceiling − actual) to the payer
                                └──▶ 200 + data

The ceiling

The 402 challenge advertises a spending ceiling, not the final price:

ceiling = base price × max multiplier

The payer signs that ceiling once, as a single EIP-3009 authorization on USDC over Base. Signing happens before your upstream has done any work, so the ceiling is the most the caller can ever be charged for the request. There is no second signature and no follow-up approval.

Reporting actual usage

After the payment settles, Meter proxies the call to your upstream and reads a multiplier from a response header you configure. Your service decides what the number means; Meter only multiplies by it.

{
  "pricing_model": "metered",
  "metered_config": {
    "basis": "complexity",
    "base_atomic": "10000",
    "min_mult": 1.0,
    "max_mult": 3.5,
    "units_header": "X-Complexity"
  }
}
FieldWhat it sets
basisWhat the multiplier measures: complexity, tokens, time, or units. Informational, it labels the receipt
base_atomicThe base price in atomic USDC (6 decimal places) before the multiplier
min_mult / max_multThe clamp. ceiling = base_atomic × max_mult
units_headerThe response header your upstream reports the multiplier in, for example X-Complexity

A response that reports X-Complexity: 2.0 against a base_atomic of 10000 (that is $0.01) is charged $0.02, against a signed ceiling of $0.035.

Fail-safe pricing

The actual charge is always clamped into the configured range:

actual = base_atomic × clamp(multiplier, min_mult, max_mult)

A missing header, a malformed value, or a non-positive number falls back to the minimum multiplier, not the maximum. A silent upstream charges the buyer the least, so a bug in your service can never overcharge a caller. To charge more than the floor, your upstream has to say so explicitly.

The clamp also means the actual charge can never exceed the ceiling the payer signed, whatever the header claims.

The refund

The difference between the ceiling and the actual charge goes back to the payer on-chain, automatically, with no action from either side:

refund = ceiling − actual

The refund is claimed before it is sent and keyed on the settlement transaction, so a crash mid-flight never double-refunds. A background pass reconciles anything left in flight: it re-sends a stale claim and confirms a broadcast transaction against chain state, because a broadcast is not yet a refund.

Sub-cent dust is the one exception. Below a small threshold an on-chain refund costs more in gas than it returns, so it is waived and recorded rather than sent. The waiver is written down; it does not vanish.

The receipt

The receipt is sealed at the ceiling during settlement, then re-sealed once the call is metered, carrying all three amounts:

FieldMeaning
authorizedThe ceiling the payer signed
chargedWhat the call actually cost
refundedWhat went back on-chain

Alongside them, metering records the basis, the reported units, and the unit_price. The hash chain is rebuilt and re-signed on the update, so the audit chain still verifies end to end.

Reading earnings

GET /v1/paywalls/:id/stats reports the ceiling and the actual side by side:

{
  "settled_count": 128,
  "gross": "4.48",
  "refunded": "1.92",
  "net": "2.56"
}

gross is the sum of the ceilings payers authorized, refunded is what went back to them, and net is what you actually earned. On a metered paywall the gap between gross and net is the feature working, not revenue lost.

  • Gate: the x402 gateway a metered paywall runs on.
  • Paywalls API: pricing_model and the full field reference.
  • Audit chain: how the re-sealed receipt stays verifiable.
Meter | CodeSpar