Essay

Anatomy of a verified transaction

Every request and response from a real run where an agent's next purchase depended on a verification verdict. Two chains, one that passed and one that failed, half a cent total.

An agent bought work from a paid API, paid Spoolis to check the delivery against rules fixed beforehand, and only made the next purchase when the check passed. Here is every hop, with the real bytes.

Two chains ran. One was designed to pass. One was designed to fail. Total spend across both: $0.00504, settled as USDC on Base over x402.

If you want the story version of this pattern, read what happens when an agent checks the work before spending more. This post is just the wire format.

0. The agreement comes first

Before any money moved, the rules were fixed in code. Chain A:

[{ "description": "The lookup result includes address, name, and query",
   "deterministic_check": { "checker": "completeness",
                            "required_fields": ["address", "name", "query"] } }]

Chain B, written to be unmeetable (the seller never returns an email):

[{ "description": "The lookup result includes a contact email",
   "deterministic_check": { "checker": "completeness",
                            "required_fields": ["email"] } }]

Writing the conditions before the purchase is the whole point. A check you invent after seeing the delivery isn't an acceptance gate, it's a rationalization.

1. Buy the work

The seller is agenttoll, a public basename lookup API. Nothing special about it: it was cheap, public, and returns JSON. It didn't know Spoolis was in the loop.

GET https://agenttoll.app/api/base/name/agenttoll.base.eth
-> 402 Payment Required   (quote: $0.001 USDC on Base)
GET again with the signed payment header
-> 200

The delivery:

{ "address": "0xe55359021a6a22d8385b827405991c56075f56f8",
  "name": "agenttoll.base.eth",
  "query": "agenttoll.base.eth",
  "at": "..." }

2. Pay to verify it

Same x402 dance, different seller: Spoolis. The request carries the agreement and the delivery, nothing else.

POST https://spoolis.com/api/v1/verify/x402
-> 402 Payment Required   (quote: $0.00102)
POST again with the signed payment header, body:
{ "settlement": "external",
  "max_amount_cents": 1,
  "unit": { "total_units": 1, "unit_amount_cents": 1 },
  "conditions": [ ...the chain A agreement above... ],
  "evidence": { "type": "dataset",
                "provenance": "api_response",
                "rows": [ ...the delivery above... ] } }

3. The verdict

{ "accepted": 1, "rejected": 0, "uncertain": 0,
  "earned_cents": 1,
  "unit_results": [{ "unit": 1, "verdict": "pass" }],
  "receipt": { "id": "ocr_f0d656c4afc7b5b876c33807", ... } }

The workflow gate is one line: only a pass verdict releases the next purchase.

4. The released purchase

Chain A's second buy used the address field from the verified delivery as its input:

GET https://agenttoll.app/api/base/name/0xe55359021a6a22d8385b827405991c56075f56f8
-> 402 -> paid -> 200

The second purchase existed only because verification accepted the first one.

That's the dependency the whole pattern is about.

5. The chain that stopped

Chain B ran the same two hops with the unmeetable rules. The verdict:

{ "accepted": 0, "rejected": 1, "uncertain": 0,
  "earned_cents": 0,
  "unit_results": [{ "unit": 1, "verdict": "fail",
                     "reasons": ["nulls.absent"] }],
  "receipt": { "id": "ocr_24f38967e6d42c65aa43ff33", ... } }

No second purchase. No transaction exists for it. The chain stopped there. Total spend: $0.00202.

6. The receipt, field by field

Both receipts are public and unauthenticated:

GET https://spoolis.com/api/v1/receipts/ocr_24f38967e6d42c65aa43ff33

The fields that matter, from the failing one:

{ "id": "ocr_24f38967e6d42c65aa43ff33",
  "schema": "spoolis/outcome-receipt@1",
  "result": "fail",
  "units": { "total": 1, "accepted": 0, "rejected": 1, "uncertain": 0,
             "rejection_summary": [{ "count": 1, "reason": "nulls.absent" }],
             "unit_results_digest": "0a2555c1..." },
  "amounts": { "asset": "USD", "committed": "0.01", "earned": "0.00" },
  "agreement": { "spool_id": "spl_8df72e32...", "agreement_hash": "..." },
  "evidence_root": "...",
  "algorithm": "Ed25519",
  "signature": "...",
  "signing_key_id": "..." }

Reading it:

  • result and units say what happened, per unit, with the reason.
  • committed vs earned is the money story in two numbers: $0.01 was at stake, $0.00 was earned. Authorization is not earned value.
  • agreement_hash pins the rules that were checked. You can't swap the agreement after the fact without the hash changing.
  • evidence_root pins the evidence that was checked.
  • The Ed25519 signature over all of it means a third party can verify the record without trusting my logs.

What this doesn't prove

  • I controlled the buyer. agenttoll is a public API I paid like anyone else; it isn't a customer or partner and didn't know about the test.
  • One seller, one wallet, deterministic field checks. Harder judgment calls are a different post.
  • The run was marked as internal testing and excluded from our metrics.

The shape

Three hops, two sellers, no shared integration between them. The only coupling is the Outcome: work was bought, checked against rules that existed before the purchase, and the next dollar moved or didn't based on the result.

Go deeper: what is an Outcome receipt, pay per verified unit, or run the same check yourself with curl from the docs.

Notes

The run happened on 2026-09-02. Both receipts above are live and fetchable; payments settled as USDC on Base over x402. The evidence file, including the corrected driver-bug note from the run, lives in the repo at docs/research/agentcash/chained-spend-evidence-live.json.

Anatomy of a verified transaction · Spoolis