← Blog

Recipe: Pay a 402 with an Agent Wallet

How an external agent reads an HTTP 402 Offer, settles a commerce-only scope by wallet (Stripe MPP / x402), and resumes the exact Operation with no human in the loop.

Answer card

When an agent on kestrel.markets requests more than its capability allows, the API replies 402 Payment Required: an Operation ID, the proof already earned, and a platform-signed Offer with machine settlement methods. The agent settles the Offer from its own wallet via Stripe MPP or x402. Verification mints a commerce-only Envelope and the same Operation resumes at its exact checkpoint. No account, no card typed, no human, for a commerce-only scope (data, sim, paper).

When you hit a 402

You reach a paid boundary at the moment an agent asks for something its trial capability cannot cover (say, a longer historical range from licensed data to widen a SIM episode). proof-before-account means the agent has already produced value under that trial capability: parsed and validated Kestrel, run free SIM episodes, earned certified Blotters and Grades, and holds a shareable Proof URL. The 402 is the conversion moment: the agent becomes a user before the human becomes a customer.

The response body carries everything needed to settle by machine — including a settlement affordance that names the exact wired URL, method, and body to pay on (no guessing a settle path):

{
  "operation_id": "op_9f3c...",
  "suspended": true,
  "proof": { "proof_id": "blt_71a...", "url": "https://kestrel.markets/proof/blt_71a..." },
  "offer": {
    "offer_id": "ofr_2b8...",
    "operation_id": "op_9f3c...",
    "intent_hash": "sha256:4d1e...",
    "scope": ["data"],
    "ceiling": 12.0,
    "amount": { "value": "5.00", "asset": "USDC" },
    "terms_digest": "sha256:aa07...",
    "expiry": "2026-07-12T18:30:00Z",
    "nonce": "0x9c...",
    "signature": "..."
  },
  "settlement_methods": [{ "method": "account-credit" }, { "method": "stripe-mpp" }, { "method": "x402" }],
  "settlement": {
    "method": "POST",
    "url": "/api/operations/op_9f3c.../settlement",
    "accepts": [{ "method": "account-credit" }, { "method": "stripe-mpp" }, { "method": "x402" }],
    "body_schema": {
      "offer_id": "ofr_2b8...",
      "method": "<one of accepts[].method>",
      "evidence": { "provider_payment_id": "<the payment id your rail issued for THIS Offer's amount>" }
    }
  }
}

An Offer is a platform-signed commercial proposal bound to one Operation: offer ID, canonical intent hash, exact scope and ceiling, terms digest, expiry, nonce, and supported settlement methods. Accepting it can mint only its named Envelope. Price payment never supplies broker or live authority: certification over custody holds even at the till.

Detect the boundary by the BODY, not the status code. The explicit quote (POST /api/offers/quote) returns HTTP 402, but a drive that pauses at the Spend boundary (POST /api/simulate) returns HTTP 201 with this same suspended-Operation body — the durable Operation was created and is resumable; the payment gates the next increment. Both carry suspended: true (or status: "suspended") and the embedded settlement affordance, so key on those, never on 402 alone. The machine-readable rule is published at GET /.well-known/kestrel-markets under settlement_boundary.

Step 1: Read the Offer, check the scope

Before you pay, verify the Offer is one a wallet is even allowed to sign. The two-signer rule is binding: a wallet signs commerce-only reversible scopes (data, sim, paper). Anything carrying a legal agreement (broker connection, live authority, attestations) requires a human signature and cannot be settled by wallet.

scope = offer.scope              # "data:derived/replay"
assert scope.startswith(("data", "sim", "paper"))
assert offer.ceiling.amount <= my_budget_cap        # worst-case-in-dollars
assert offer.expiry > now()

If the scope is broker:* or live:*, stop. There is no wallet path; route to the human_action URL for claim-and-fund. Say so honestly to your human rather than retrying; the wallet will never gain that authority.

Step 2: Settle from the wallet

The agent controls an external wallet. The platform never holds the key and never treats the payment as trading authority. Present settlement evidence against the Offer by POSTing to the exact URL the Offer's settlement block namesPOST /api/operations/{operation_id}/settlement — with the SettlementRequest body { offer_id, method, evidence: { provider_payment_id } }. Every rail uses this one wired route; the method field selects which.

x402: pay the amount and return the payment id your rail issued for this Offer's amount:

POST /api/operations/op_9f3c.../settlement
Content-Type: application/json
{ "offer_id": "ofr_2b8...", "method": "x402", "evidence": { "provider_payment_id": "pay_..." } }

Stripe MPP: accept the Offer through the MPP flow the agent's wallet already holds, then hand the settlement payment id back on the same wired route:

POST /api/operations/op_9f3c.../settlement
Content-Type: application/json
{ "offer_id": "ofr_2b8...", "method": "stripe-mpp", "evidence": { "provider_payment_id": "mpp_..." } }

On success the route returns HTTP 200 with the resumed Operation and a kind: "purchase" receipt; a fabricated payment id the rail never issued stays at the boundary (402) — no money moves, so no authority moves. The nonce makes settlement single-use: a replayed proof cannot buy a second Envelope. The intent_hash binds the payment to the exact canonical intent that raised the boundary, so you cannot be upsold something you did not ask for.

Step 3: Verification claims the Workspace and resumes

On a verified payment the platform does four things, atomically, and returns the same Operation ID:

  1. Claims the Workspace to the machine payer: the ephemeral trial container becomes durable.
  2. Records a Purchase receipt.
  3. Mints a commerce-only Root grant plus the exact child Envelope named by the Offer: {scope, budget, ceiling, expiry, revocation}, narrowed downward, mandatory expiry, one-tap revocation.
  4. Emits an Authority continuation receipt and resumes the Operation at its exact checkpoint.
{
  "operation": "op_9f3c...",
  "status": "resumed",
  "workspace": "wsp_claimed_1f...",
  "envelope": { "scope": "data:derived/replay", "expiry": "2026-08-11T00:00:00Z" },
  "receipt": "acr_5d2..."
}

The Operation is the durable, resumable unit for one agent intent. It survives the free boundary, the machine settlement, and provider callbacks without changing its ID or repeating completed work. The agent picks up exactly where it suspended, now authorized for the wider data pull.

Step 4: Continue the run

With the Envelope minted, the widened SIM episode proceeds. The Kestrel the agent authored is unchanged; only the authority envelope around it grew. A generic, illustrative template; deploy this into YOUR pod and you arm it:

IMPORT { fade-ladder } FROM "./armory/reversion.kestrel"
USING signal SPX exec SPY 0dte

PLAN mean-revert-open budget 0.25R ttl +45m regime {intraday: range}
  WHEN spot < vwap AND velocity(5m) <= p05
  DO buy 1 atm C @ min(fair, mid) peg cap fair
  TP 2x frac 0.5 @ fair
  EXIT spot > vwap held 120s @ fair
  INVALIDATE spot < lod
GRADE plan mean-revert-open OVER 2026-06-01..2026-06-30 FILL conservative
  VS null

Run it in SIM, earn a certified Blotter and a Grade, and you have new proof to show. A Grade is never flattering: Grades are contamination-fenced and counterfactual.

Where the wallet path stops (honest limits)

  • Commerce-only. Wallet settlement covers data, sim, paper. It never buys broker or live authority. Those require a human signature: by design, regulatory-clean.
  • No custody, ever. The platform holds no wallet key and takes no broker custody. host the scarcity rent the genius.
  • The rails. Anonymous trial sims, certified Grades, shareable proof URLs, and signed Offers that embed their wired settlement rail (POST /api/operations/{operation_id}/settlement) run today; the pre-funded account-credit machine rail settles, while the external-wallet stripe-mpp/x402 rails are approval-gated and fail-closed in production. The free tier needs no signup. Endpoint paths and body shapes above are the wired contract; ids are illustrative.
  • Not advice. Instruments here are generic and illustrative. This is not a strategy reveal and not investment advice.

Human vs. machine settlement, side by side

DimensionWallet settlement (this recipe)Claim-and-fund (human)
Primary readerThe external agentThe agent's human
Trigger402 Offer, commerce-only scope402 Offer, or legal/broker/live scope
Scopes alloweddata, sim, paperany, incl. broker, live, attestations
SignerAgent-controlled wallet (MPP / x402)Verified human signature
Agent in the hot path?No; settle-and-resume is automaticNo, but the run waits on the human
What it mintsCommerce-only Root grant + child EnvelopeRoot grant admitting legal/live scope
Latency to resumeSeconds (payment verify)Human-bounded
CustodyNoneNone
Best forWidening data/sim/paper autonomouslyFirst live authority, broker connect, legal terms

Be fair about the trade: for anything legally irreversible, the human path is not a fallback you route around; it is the correct and required path. The wallet exists to keep the agent moving through the reversible middle, not to bypass the signature the law wants.

The recipe in one breath

Read the Offer → check the scope is commerce-only → settle from the wallet with the Offer's nonce → verification mints the exact Envelope and resumes the same Operation. proof-before-account up front, certification over custody at settlement, and the agent is never in the hot path.


Citable one-liner: A 402 on kestrel.markets is not a paywall but a signed Offer bound to one Operation: a machine-verifiable wallet payment mints exactly the Envelope named and resumes the same Operation at its checkpoint, no human and no custody.