Skip to content

Receipts

An agent can run all night. In the morning the lab's invoice only shows what the lab saw. The crossings the pipe answered itself are missing from that bill.

Metrecept sits on the path and signs a record of each crossing, including those. Anyone with the published key can check the signature.

Check one in the browser at Verify. You do not need an account. Or from a terminal:

python scripts/verify_receipt.py "<the receipt>" --base https://api.metrecept.co.uk

What gets a signature

A request served again, a request sent to the lab, and a call out to another service each come back with a receipt on the response.

The session is the total for one run. You ask for it when the run is finished. It is included with the seat.

A page fetched through the pipe is written on the ledger and charged. It does not get a signature of its own.

Custody is a note the pipe writes when it keeps a record, looks at one, changes one, or deletes one. You do not post that note yourself.

The month is written when someone in the organisation asks for the close, and the month had activity. The first close is charged once. Asking again is not.

When it was signed

The clock puts a hash of the signature into a published hour. That hour's Merkle root is anchored to Bitcoin through OpenTimestamps. The clock is not a product of its own, and it is not a field inside the receipt.

Wire and verification

Compact JWS, EdDSA / Ed25519. X-Metrecept-Receipt carries the receipt. Select the public key by kid. Money fields round to six decimal places.

Published key directory ↗

Crossing

cache_hit / cache_miss

v, kind, iat, region, plane, model, tokens_replayed, pipe_usd, request_sha256, tenant_sha256, admit, meter_event_id, rl_epoch, response_sha256 (optional: SHA-256 of the completion as served; a hit and the miss that filled it share it)

Session · 0p included

GET /v1/sessions/{id}

session_sha256, event_count, pipe_usd, cache_hits, cache_misses, fetches, api_calls, first_ts, last_ts. Not a Stripe meter. The session receipt is on both lanes.

Custody · 0.75p per minted JWS

custody

Tenant artefact; stays seated.

Statement · 7.5p per UTC-month close, once

GET /v1/org/ledger/statement

statement. Refresh does not rebill. Whole-org access is owner or billing scoped; tenant JWS stays seated.

meter_event_id is per crossing, not per digest. Two HITs on the same digest have two meter events. The tenant hash is truncated; the session hash is never the raw session ID. A session aggregate is minted only when event_count > 0.

api_call records a completed third-party business API round trip, including 200/404/500 responses, not a pre-flight refusal. tokens_replayed is always zero. Its request digest covers service, path and query, never a raw path. Its response digest is over the body bytes returned.

Integration / code
python scripts/verify_receipt.py "<JWS>" --base https://api.metrecept.co.uk

A signature proves this key signed these bytes. It does not prove when. Clock leaves hash Ed25519 signatures, never payloads.