← Blog
October 16, 2026 · 17 min

Settled is not final: what x402 success means on each chain

x402's settle call returns one boolean. On Base, using the reference facilitator code and Base's public RPC, that boolean came back in a median 179 milliseconds, and for 94 of 100 live settlements we watched, before the payment's block had been sealed. On Solana it means more than two-thirds of stake voted. On Cardano the seller decides. And next Wednesday, Solana replaces its consensus.

An agent pays, a facilitator settles, the seller releases the response. The x402 v2 specification describes settle as the step that "durably commits payment state for the request — establishing finality from the resource server's perspective." That phrase does a lot of work. Finality is a property of a chain, not of a perspective, and every chain x402 supports has its own ladder from "a node saw it" to "it cannot be undone."

This post asks a narrow question: when success: true comes back, which rung of that ladder are you on?

What we read and ran, all on 2026-10-16. The x402 repository at commit faa1c69: the v2 spec, the 17 exact network bindings, the TypeScript packages at 2.28.0, and the Go and Python signer interfaces. Also viem 2.57.7, x402-rs at e75adda, Base's Flashblocks FAQ and an open Base docs pull request, the OP Stack glossary, Polygon's finality page, Solana's RPC docs, SIMD-0326 and SIMD-0384, Anza's Alpenglow page, and CDP's facilitator documentation. We ran three read-only probes. The first ran x402's own EVM signer wrapper against 100 live USDC settlements on Base. The second sampled the latest, safe and finalized heads on six chains for ten minutes. The third measured Solana's slot rate and blockhash lifetime.

The short version. x402 gives the word "success" no depth. Only one binding, Cardano, lets the seller say how much evidence it wants. The EVM path accepts the first receipt it can get, and on Base's public RPC that receipt is a sequencer preconfirmation: 94 of the 100 settlements we watched resolved before their block was sealed. All 100 held. That is a fine trigger for releasing a one-cent response, and the wrong state to record as "settled." The Solana path waits for confirmed, which is sound. But the 60–90 second blockhash window its spec documents is about 25 seconds in practice. And on October 21, Alpenglow's migration puts Solana into a vote-only window where no x402 settlement can land.

What the spec promises

The v2 specification defines three payment flows. The default, authorization, runs verify, then the resource, then settle, then the response: "funds move only after it completes successfully." upfront runs settle first, "giving the server finality first." escrow settles a deposit before the resource and the final charge after it.

The SettleResponse carries success, errorReason, payer, transaction, network, an optional amount and an optional extensions object. Nothing in it says how final the transaction is. There is one non-terminal error, settlement_pending: the transaction "was broadcast but its confirmation could not be established." It must carry the hash so the caller can reconcile on chain. We covered the verify and settle contract itself in our facilitator deep dive. The question here is what "confirmation" means inside it.

The exact scheme's family rules come closest. They split methods into two families. Client-submitted methods, where the payer broadcasts and presents a proof, MUST "declare the observable event that makes a payment final and which party owns confirmation-depth policy." Facilitator-submitted methods, where the client signs and the facilitator broadcasts, must declare their fee payer, replay primitive, validity window and duplicate-submission behavior. They do not have to declare finality. EVM and SVM, the two families most x402 traffic runs on, are facilitator-submitted.

One binding fills the gap anyway. The Cardano binding adds extra.confirmationPolicy.l1Confirmations, an integer from -1 to 20 that defaults to 1. The seller chooses it in the 402, and a facilitator can advertise the range it supports in /supported. Minus one means mempool acceptance. The spec calls granting access on mempool status "strongly discouraged," because Ouroboros Praos "has probabilistic finality." It is the only binding where finality depth is a field on the wire.

What each implementation waits for

If the spec does not define the depth, the code does. Here is what each settle path waits for before it reports success, read from the repository at faa1c69 and from x402-rs.

// Settle returns success: true when...
EVM  (TypeScript)  first receipt with status success; viem waitForTransactionReceipt,
                   confirmations left at the default of 1, 180 s timeout
EVM  (Go, Python)  signer interface takes a hash and nothing else; no confirmations knob
EVM  (x402-rs)     1 confirmation, 30 s receipt timeout
SVM  (TypeScript)  getSignatureStatuses reports confirmed or finalized; 30 s budget
SVM  (x402-rs)     CommitmentConfig::confirmed()
Starknet           ACCEPTED_ON_L2 plus a block_number; spec names the L2 reorg risk
NEAR               tx status with wait_until FINAL
Cardano            seller-chosen l1Confirmations; default one block
Algorand           inclusion; spec: no forks, instant finality
Concordium         ConcordiumBFT finalization (~10 s per the spec)
Stellar            getTransaction status SUCCESS, polled 15 times at 1 s
XRPL               validated: true and tesSUCCESS

The spread is wide. NEAR, Concordium, Algorand, Stellar and XRPL settle on a ledger state their bindings describe as final. Starknet and Cardano settle earlier and say so. The Starknet binding states that ACCEPTED_ON_L2 "is a sequencer commitment prior to L1 finality and can, in rare cases, be reverted in an L2 reorg," and that waiting for ACCEPTED_ON_L1 removes the risk "at the cost of hours-scale latency." EVM and SVM settle earlier too, and their bindings say nothing about it.

x402-rs adds one confusing label. Its chain config documents the flashblocks flag as "whether this chain supports flashblocks (immediate block finality)." In the code, the flag only switches gas estimation from the pending block to latest. Flashblocks are preconfirmations, not finality, as Base's own documentation makes clear below. We covered the rest of that codebase in our x402-rs audit.

Base: success before the block exists

Base produces a block every two seconds and streams Flashblocks inside each one, "200ms incremental block updates." A Flashblock is a sequencer preconfirmation. Base's FAQ says it "targets a Flashblock reorg rate of < 0.1%," where a reorg means "a Flashblock was streamed as a preconfirmation but wasn't included in the final block." If conditions turn unsafe, "preconfirmations are disabled network-wide and confirmations fall back to standard 2-second blocks."

The same FAQ says eth_getTransactionReceipt "returns preconfirmed receipts." Base's reference page for that method still says receipts exist only for mined transactions. An open pull request, base/docs#2081 from October 6, documents the contradiction. It reports that mainnet.base.org returned a receipt for the not-yet-sealed block, with a zero blockHash, in 4 of 5 tries.

Now connect that to x402. The TypeScript EVM facilitator waits through toFacilitatorEvmSigner, which calls viem's waitForTransactionReceipt with a timeout and no confirmations argument. In viem 2.57.7, when confirmations is 1 or less, the first receipt eth_getTransactionReceipt returns resolves the wait immediately. viem's base chain definition uses https://mainnet.base.org as its default RPC. And the x402 example facilitators create their viem clients with transport: http() and no URL. Settle then checks status and, for EIP-3009, the Transfer event in the receipt's logs. A preconfirmed receipt has both.

We measured it. For about three minutes we polled Base's pending block on mainnet.base.org. We picked out calls to USDC's transferWithAuthorization (both selectors, 0xe3ee160e and 0xcf092995), the EIP-3009 path x402's exact scheme settles through. For each one whose block was not yet sealed, we ran the wait through x402's own signer wrapper.

import { toFacilitatorEvmSigner } from '@x402/evm'; // 2.28.0
const signer = toFacilitatorEvmSigner({
  address: ZERO_ADDR,
  waitForTransactionReceipt: a => publicClient.waitForTransactionReceipt(a),
});
// same call the exact EVM settle path makes after broadcasting
const receipt = await signer.waitForTransactionReceipt({ hash });
const sealed = await publicClient.getBlockNumber();
// preconfirmed if receipt.blockNumber > sealed, or blockHash is all zeros

Results for 100 settlements in blocks 52,676,318 to 52,676,397:

These were settlements by whoever sent them; we only watched. The result is not a bug report. Base's preconfirmations held in every case we saw, and the target reorg rate is published. The point is the label. When the reference code says success: true on a Flashblocks endpoint, it means "the sequencer has promised to include this," not "this is in a block," and certainly not "this is final."

The ladder, measured

Above the preconfirmation, every chain has more rungs. The OP Stack glossary defines them for Base. An unsafe block is one "not derived from the L1 chain." A safe block "can be derived entirely from L1." The finalized head is the highest block derived from finalized L1 blocks, "older than two L1 epochs (64 L1 time slots)." Polygon's finality page says that since Heimdall v2, "deterministic finality is now achieved in 2 to 5 seconds," and that deterministic means "there is no chance of a reorganization once a block is finalized." Solana's RPC docs define confirmed as "a block directly voted on by a supermajority of stake," and finalized as a block "finalized with maximum lockout."

We sampled each chain's tip against its safe and finalized tags 20 times, every 30 seconds, between 09:03 and 09:14 UTC on October 16. The numbers below show how far behind the tip each tag ran: the median, then the range.

chain          safe lag              finalized lag
Base           48 s  (16–88 s)       17.9 min (14.5–20.1 min)
OP Mainnet     90 s  (24–158 s)      19.5 min (15.6–24.3 min)
Arbitrum One   11.3 min (7.4–14.3)   18.8 min (14.9–21.6 min)
Ethereum       10.0 min (6.4–12.6)   16.4 min (12.8–19.0 min)
Polygon PoS    (no safe tag)         3 s  (0–5 s)
Solana         confirmed 0–1 slots   finalized 32–33 slots (~7 s)

Two things stand out. On Base, the gap between the moment the reference code reports success and the moment the payment is final is about 18 minutes: roughly 0.2 s to preconfirmation, two seconds to a sealed block, a minute to safe, then the rest of the way to finalized. On Polygon the whole ladder is about three seconds, so waiting for finalized costs almost nothing. The Polygon RPC we used rejected the safe tag outright: "safe block not found."

Solana: a sound level and a shorter clock

The SVM settle path makes a defensible choice. It polls getSignatureStatuses and returns once the status reads confirmed or finalized, with a 30-second budget. In our samples confirmed ran 0 to 1 slots behind processed, and finalized 32 to 33 slots behind. We walked through the rest of the SVM settlement path in our Solana exact-scheme post.

The clock is the problem. A Solana transaction is valid for 150 blocks after its blockhash. The SVM binding puts that at "~60–90 seconds," and the duplicate-settlement cache constant is commented the same way. The confirmation loop's comment assumes "Solana slots are ~400ms." Mainnet is faster now. Block times say 100,000 slots took 21,573 seconds, or 215.7 ms per slot. A direct count showed block height rising 290 in 61 seconds.

When the 402 carries no recentBlockhash, the x402 SVM client fetches its own with getLatestBlockhash() and no commitment argument, which the RPC serves at its finalized default. In five probes, the returned lastValidBlockHeight sat 118 blocks above the current processed height. At today's rate, that is about 25 seconds from the moment the client asks to the moment the payment can no longer land.

Under the default authorization flow, those 25 seconds must cover signing, the retry request, verify, the entire resource handler and the settle broadcast. The binding already says: "Resource servers with long-running handlers SHOULD use payment flow upfront." At current slot times, "long-running" starts around 20 seconds. LLM calls with long reasoning or long outputs can take more than that. This is the same verify-to-settle window as the two-phase gap, failing from the other end: the handler runs, settle fails because the blockhash expired, and the seller has done the work for nothing.

October 21: Solana changes its definition

Solana's commitment levels are about to mean something new. SIMD-0326 replaces TowerBFT with Alpenglow. Its voting component finalizes a block after one round of votes from 80% of stake ("fast-finalization"), or two rounds from 60% ("slow-finalization"). Anza's Alpenglow page lists testnet and devnet as completed, mainnet-beta for 10/21, and "150ms" finality.

The migration, specified in SIMD-0384, is the part an x402 operator has to plan for. A feature gate activates at an epoch boundary. Five thousand slots later comes the migration boundary. From then on, blocks carry only vote transactions and any other transaction marks the block dead. In the SIMD's words: "Core code will stop notifying RPC services of any optimistic confirmation/commitment updates." Validators then gather genesis votes from at least 82% of stake. When they have them, they roll back everything after the Alpenglow genesis block, hand consensus to Votor, and "re-enable packing non-vote transactions, enable Alpenglow rooting, and re-enable RPC commitment/confirmation reporting." The SIMD's stated goal is a handoff "that doesn't rollback TowerBFT confirmed user transactions."

Our arithmetic, from getEpochInfo on October 16: epochs are 432,000 slots, and at the current slot rate the boundary that lands on October 21 is epoch 1064, at slot 459,648,000. That would put the migration boundary at slot 459,653,000, with 5,000 slots of TowerBFT in between, about 18 minutes at 215 ms. The feature account named in SIMD-0384, a1penGLz8Vm2QHYB3JPefBiU4BY3Z6JkW2k3Scw5GWP, did not exist on mainnet-beta when we queried it. getAccountInfo returned null, at RPC version 4.3.0.

Here is what that means for an x402 SVM settle submitted inside the vote-only window. The transaction cannot be packed. The facilitator's 30-second confirmation loop will not see confirmed, because commitment reporting is paused. It returns settlement_pending with a signature whose blockhash will expire before user transactions resume. Under authorization, the seller has already run the handler. Under upfront, the buyer gets an error before any work is done.

After the handoff, the gap between confirmed and finalized that we measured at 32 slots is expected to shrink to Alpenglow's finality time. SIMD-0326 does not say how the RPC commitment levels map onto Alpenglow's certificates. Re-measure before you rely on the new numbers.

What success should carry

None of this needs a new protocol. It needs the depth to be said out loud, in three places.

In the settle response. SettleResponse already has an extensions object. A facilitator can report the level it actually observed:

{
  "success": true,
  "transaction": "0x…",
  "network": "eip155:8453",
  "extensions": {
    "confirmation": {
      "level": "preconfirmed",      // | "unsafe" | "safe" | "finalized" | "confirmed"
      "blockNumber": "52676397",
      "blockHash": null,               // unknown until sealed
      "observedAt": "2026-10-16T09:21:04Z"
    }
  }
}

In the requirements. Cardano's confirmationPolicy is a working template. The EVM and SVM bindings could accept the same field with chain-native levels: preconfirmed, unsafe, safe and finalized on OP Stack chains; confirmed and finalized on Solana. The facilitator would advertise its range in /supported, just as the Cardano binding already allows.

In the bindings. The exact family rules already require client-submitted methods to name their finality event and who owns depth policy. Extending that to facilitator-submitted methods would make EVM and SVM state what Starknet and Cardano already state.

The economics are simple. A seller that releases on preconfirmation and books on finalization has, at any moment, roughly its revenue per minute times 18 minutes in flight on Base, and times three seconds on Polygon. That exposure is acceptable at one cent per call. It still has to be known before it can be accepted.

What it means for LLM4Agents

Our walk-up x402 rail settles USDC on Base through hosted facilitator infrastructure. We do not run the receipt wait ourselves, so the depth behind the success we receive is the facilitator's choice, not ours. The hosted documentation we read, CDP's settlement-pending page, describes a transaction whose "final confirmation" was not observed "within the synchronous settlement window." It does not say which level that is.

For releasing a response, that is fine. Our prices are cents per call, the Flashblock reorg target is under 0.1%, and nothing in our probe failed. Waiting a minute for safe or 18 minutes for finalized would make an HTTP API unusable. For our books, it is not fine. A payment row that reads "settled" while the chain says "preconfirmed" is a record that can be wrong for 18 minutes. Today nothing in the response tells us which state we got.

Agents meet the same ambiguity from the other side. An agent that checks the transaction hash in our payment response against an RPC without Flashblocks may find nothing for a block or two. One that reads the receipt from a Flashblocks endpoint will see an all-zero block hash. Neither is a failed payment, and neither is documented anywhere an agent would look.

Solana and Polygon are where this turns into design decisions. If we add a Solana walk-up rail, a 25-second blockhash window rules out authorization for long LLM calls. We would need upfront, or an escrow-based upto, which is how CDP's documentation describes Solana upto: "one onchain escrow deposit and a second onchain settlement." Any Solana rail also needs a runbook for October 21. Polygon goes the other way: with deterministic finality in a few seconds, it is the one network where waiting for finalized before releasing is almost free.

There is an opportunity here too. Nothing in the x402 response format tells an agent how final its payment is today. A receipt that says "preconfirmed at block N, finalized at 09:39 UTC" is concrete, verifiable and cheap to produce. It is the kind of detail that makes a payment rail auditable by the machines paying it.

Staying on the frontier

1. Record the level, not just the hash. For every walk-up payment, store the block number, the block hash (all zeros means preconfirmed) and the level observed at settle time. Run a reconciler that promotes each row to safe and finalized using the chain's own tags. Alert on any transaction that disappears or changes block.

2. Separate release from booking. Keep releasing responses on the facilitator's success. Recognize revenue only at finalized: about 18 minutes on Base and seconds on Polygon. Report in-flight value as its own number.

3. Put the level in our receipts. Add a confirmation object, shaped like the example above, to our payment-response extensions and to a response header. Document what a zero block hash means. Agents should not have to rediscover this probe.

4. Push it upstream. Open an x402 issue proposing a confirmationPolicy for the EVM and SVM bindings modeled on Cardano's, plus a settle-response confirmation extension. Separately, propose correcting the SVM binding's "~60–90 seconds" to a figure stated in blocks, with today's measured time next to it.

5. Choose the payment flow by handler duration and chain. Before any Solana walk-up ships, default LLM calls to upfront or escrow-based upto. If authorization is ever used there, fetch the blockhash at confirmed, supply it in the 402, and cap the handler at about 20 seconds.

6. Run an Alpenglow runbook on October 21. Watch for the feature account a1penGLz…5GWP to appear. From activation until commitment reporting resumes, drop Solana from any accepts array and treat settlement_pending there as expected. Afterwards, re-measure the slot rate, the gap between confirmed and finalized, and the blockhash window, then update every timeout that depends on them.

7. Re-run these probes weekly. Track the Flashblocks preconfirmation rate on our settle path, the safe and finalized lags on every chain we accept, and Solana's slot rate. Any of them can change what "success" means, and no such change would be announced inside x402.

Pay per call, in stablecoins, over an OpenAI-compatible API

One 402, one signature, 345+ models. No subscription, no minimum.

Register your agent