Stipendex

Envelope: Quote / Proof / Receipt

Three objects describing one payment. Shared rules: JWS (Ed25519), amounts as decimal strings, stipendex: "<type>/0.1". Mandate and Confirmation — mandate-wallet.md.


Quote — the receiver's offer

A single-use offer: "pay X — get Y". Issued by the receiver in response to an unpaid call (see transports.md).

{
  "stipendex": "quote/0.1",
  "quote_id": "q_8f3d1c…",
  "receiver": {
    "id": "mcp:exa-search",
    "key": "ed25519:GfHq…",
    "registry": "https://registry.4agents.io/receivers/exa-search"
  },
  "amount": { "value": "0.0042", "currency": "USD" },
  "description": "web_search: ~3k tokens",
  "rails": [
    { "scheme": "account", "facilitator": "https://pay.4agents.io" },
    { "scheme": "x402", "network": "base", "asset": "USDC", "to": "0x9a…" }
  ],
  "session": { "id": "s_42", "mode": "tab", "cap": "5.00" },
  "expires_at": "2026-07-16T12:05:00Z",
  "sig": "<receiver JWS>"
}
Field Req. Rules
quote_id yes single-use; a second presentation MUST be rejected
receiver.id yes stable identifier (mcp:<slug> or URL)
receiver.key yes signing key; MUST match the key in the registry descriptor if the receiver is verified
receiver.registry no link to the trust registry descriptor
amount or estimate yes (exactly one) amount — fixed price (service); estimate — estimate with tolerance (checkout/metered), below
description yes human-readable: shown to the principal during HITL
rails[] yes acceptable settlement schemes; per-scheme fields in rails.md
session no a tab-aggregation offer, below
expires_at yes SHOULD: minutes for service, 10–15 minutes for checkout

estimate + tolerance (amounts unknown upfront)

For metered tools and goods checkout the final amount is known only after execution (tokens, shipping, tax, feed price drift):

"estimate": {
  "value": "84.00",
  "currency": "USD",
  "tolerance": { "value": "8.40" }
}

Semantics: the wallet authorizes (holds) estimate + tolerance; only the confirmed final amount ≤ estimate + tolerance may be captured (invariant I3). Exceeding the tolerance is not an "over-capture" but a new cycle: re-quote and re-confirmation. The mechanics are borrowed from 4agents order-flow v2.1 ("ACCEPT is the source of truth for the amount").

session — tab session (micropayment aggregation)

Per-call settlement is expensive and unnecessary for micro-amounts. A receiver MAY offer a tab:

Proof — proof of payment

Issued by the wallet after successful settlement (or hold) on the chosen rail.

{
  "stipendex": "proof/0.1",
  "proof_id": "p_c81a…",
  "quote_id": "q_8f3d1c…",
  "mode": "capture",
  "scheme": "account",
  "evidence": "<rail-specific: facilitator JWS | tx hash | payment_intent id>",
  "mandate_ref": "sha256:9e1b…",
  "confirmation_id": null,
  "payer_key": "ed25519:BBBB…",
  "sig": "<wallet JWS>"
}
Field Rules
mode capture (charged, service) or hold (authorized, checkout)
evidence rail-verifiable proof; format is per-scheme (rails.md)
mandate_ref hash of the mandate, not the mandate itself — the principal's limits and allowlist are not disclosed to the receiver (privacy); the full chain is available to the principal and, in a dispute, to the facilitator
confirmation_id reference to a Confirmation when HITL occurred (mandatory for checkout)

Idempotency: a receiver that has seen a proof_id before MUST return the previous result/Receipt without re-execution or re-charging.

Receipt — the receiver's acknowledgement

Issued by the receiver after execution. Closes the cycle and serves as evidence in audit and disputes.

{
  "stipendex": "receipt/0.1",
  "receipt_id": "r_11ac…",
  "quote_id": "q_8f3d1c…",
  "proof_id": "p_c81a…",
  "status": "settled",
  "amount_final": { "value": "0.0042", "currency": "USD" },
  "result_hash": "sha256:44fe…",
  "issued_at": "2026-07-16T12:04:31Z",
  "sig": "<receiver JWS>"
}
status Meaning
settled charged and executed (service happy path)
held authorized, execution awaits confirmation (checkout before ACCEPT)
captured final amount charged after confirmation (checkout after ACCEPT)
voided hold released without charge (DECLINE / timeout / out of tolerance)
refunded refund (extension; the refund itself is executed by the rail)

result_hash — hash of the call result (service) or the order identifier (checkout). The link proof → receipt(result_hash) is the proof of "paid and received / did not receive".

Idempotency and retry summary