On this page
In x402, the resource server decides whether a request is paid, but it rarely checks signatures or talks to a blockchain itself. It hands the client's payment to a facilitator: a service that verifies the authorization and settles it on a network. The x402 V2 core specification lets a resource server delegate this to a third party or host the endpoints itself. Either way, a facilitator error decides whether paid content leaks for free or a client pays twice.
Checked on Oct 13, 2026
Protocol statements on this page follow section 7 (facilitator interface), section 9 (error handling) and section 10 (security considerations) of the V2 core specification, and the exact EVM scheme. The scheme catalog evolves; re-read the specification before relying on a detail.
The three facilitator endpoints
| Endpoint | What it does | Answer |
|---|---|---|
POST /verify | Checks a payment authorization against the payment requirements without executing it. It is read-only: it must not commit payment state or write on chain. | VerifyResponse: isValid, and invalidReason when it is false. |
POST /settle | Durably commits the payment, typically by broadcasting a transaction. It can be called more than once for one payment, as in the escrow flow. | SettleResponse: success, transaction, network, and errorReason on failure. |
GET /supported | Lists what the facilitator can process. | kinds (version, scheme, network), extensions and signers per CAIP-2 pattern. |
Both POST endpoints take the same body: x402Version, the client's paymentPayload and the paymentRequirements it should satisfy. The resource server should send its own requirement there, not the copy the client echoed in accepted.
When /verify runs: payment flows
The payment flow decides which endpoints run, and in which order, around the resource handler:
| Flow | Order | Pre-handler check |
|---|---|---|
authorization (default) | verify, resource, settle, respond | /verify |
upfront | settle, resource, respond | /settle; /verify is not part of this flow |
escrow | settle, resource, settle, respond | The first /settle, which commits a deposit or ceiling |
The specification's invariant: a verify or a settle must run before the resource executes. Under the default flow, that makes /verify the only thing standing between a forged signature and the protected handler.
What goes wrong
These are risks to look for in any facilitator, with the control the specifications imply for each.
| Risk | Effect | Control |
|---|---|---|
| /verify accepts a forged signature | Under the authorization flow the resource runs for a payment that can never settle: the content leaks for free. | Recover the signer from the EIP-712 digest and require it to equal authorization.from; reject the zero address. See the EIP-3009 guide. |
| /verify writes state | Funds or nonces are committed before the handler runs, although the authorization flow promises funds move only after it succeeds. | Keep /verify free of on-chain writes; commit only in /settle. |
| Capability drift | A resource advertises a scheme or network that the facilitator does not list, so payments fail at verification. | Keep each resource's accepts within the facilitator's /supported kinds, for the same x402Version. |
| Missing signers | A network with no entry in signers leaves integrators without the address that signs for it. | Publish signer addresses for every network, or for a namespace wildcard such as eip155:*. |
settlement_pending retried blindly | A new authorization carries a new nonce, so it can settle on top of the first transaction: the client pays twice. | Return the broadcast hash and network, and reconcile on chain before any retry. See the error codes reference. |
| Replay of an authorization | A captured signature is submitted again or on another chain. | EIP-3009 nonces are single-use on chain, validBefore limits the lifetime, and the EIP-712 domain binds the signature to one chain and token. |
One thing a facilitator cannot do on the EVM exact scheme is change the amount or the destination: both are inside the payer's signed message, and the scheme specification limits the facilitator to broadcasting the transaction.
What Settlens tests
A facilitator scan reads GET /supported passively. The /verify checks run only during an active probe that the endpoint owner authorized in writing. The table is generated from the Settlens check catalog.
| Check id | What it verifies |
|---|---|
facilitator.reachable | GET <facilitator>/supported returned an HTTP response within the timeout. Redirects are not followed. Mode: facilitator · severity: high |
facilitator.response_body_limit | The /supported response is at most 1 MiB. Mode: facilitator · severity: high |
facilitator.supported_status | GET /supported returned HTTP 200. Mode: facilitator · severity: high |
facilitator.content_type | The /supported Content-Type is application/json or another +json media type. Mode: facilitator · severity: medium |
facilitator.https | The facilitator URL uses HTTPS, or loopback HTTP for local testing. Mode: facilitator · severity: medium |
facilitator.supported_schema | The body has a non-empty kinds array (each with a positive integer x402Version, a scheme and a network, CAIP-2 for V2 kinds), an extensions array of strings and a signers object mapping networks to string arrays. Mode: facilitator · severity: high |
facilitator.v2_capability | At least one supported kind has x402Version 2. Mode: facilitator · severity: high |
facilitator.duplicate_kinds | No x402Version, scheme and network combination appears twice in kinds. Mode: facilitator · severity: low |
facilitator.requirement_coverage | Every scheme/network pair advertised by the resource appears in the facilitator's /supported kinds for the same x402Version. Skipped when /supported is invalid or unavailable. Mode: facilitator · severity: high |
facilitator.signer_coverage | Every advertised network has a non-empty signer list in /supported, either for the exact network or for its namespace wildcard (for example eip155:*). Mode: facilitator · severity: medium |
facilitator.verify_reachable | During an authorized active probe, POST <facilitator>/verify with the intentionally invalid payload completed. Reported as a warning only when it could not complete. Mode: active · severity: medium |
facilitator.verify_response_schema | The /verify answer to the intentionally invalid payload is a JSON object with a boolean isValid field. Mode: active · severity: high |
security.facilitator_rejects_invalid_signature | /verify returns isValid=false for the intentionally invalid, all-zero signature. Settlens never calls /settle. Mode: active · severity: critical |
Two runs against the bundled demo target show the checks that matter most. Here the facilitator does not list the Base Sepolia kind that the resource advertises:
settlens scan http://127.0.0.1:4402/secure \
--facilitator http://127.0.0.1:4402/facilitator-empty --no-write
Settlens x402 assessment 96327c63
Targets 1 · Active 0 · Settlement calls 0
127.0.0.1 GET http://127.0.0.1:4402/secure
22 pass · 1 fail · 0 warn · 0 skip
FAIL high Facilitator covers advertised payment requirements
1 advertised payment choice(s) are absent from facilitator capabilities.
Total: 22 pass · 1 fail · 0 warn · 0 skip
Here the facilitator's /verify answers isValid: true to an all-zero signature. The probe sends that one invalid payload and never calls /settle:
settlens scan http://127.0.0.1:4402/secure \
--facilitator http://127.0.0.1:4402/facilitator-accept \
--active --authorized --authorization-ref DEMO-APPROVAL-003 --no-write
Settlens x402 assessment 513cfb74
Targets 1 · Active 1 · Settlement calls 0
127.0.0.1 GET http://127.0.0.1:4402/secure
26 pass · 1 fail · 0 warn · 0 skip
FAIL critical Facilitator /verify rejects an invalid signature
The facilitator reported isValid=true for an intentionally invalid, all-zero signature.
Total: 26 pass · 1 fail · 0 warn · 0 skip
What an outside test cannot prove
- Settlement. Settlens never calls
/settleand never moves funds, so it cannot show that a facilitator settles the right amount once, or handlessettlement_pendingcorrectly. - Chain state. Balance checks, nonce use and transaction simulation need an RPC node; Settlens works without one.
- Read-only
/verify. A single invalid probe cannot observe whether/verifywrites state for valid payloads. - Valid payments. The probe proves that one forged signature is rejected, not that every valid payment is accepted.
For these, review the facilitator's code and settlement records. The facilitator section of the x402 security checklist lists every control, and Settlens for facilitators describes how operators use the scans. Check ids and fixes are in the check reference.
Frequently asked questions
Is the x402 facilitator /verify endpoint allowed to change state?
No. The x402 V2 specification defines /verify as read-only: it must not commit payment state or write on chain. Only /settle commits the payment.
Can an x402 facilitator change the amount or the recipient?
Not on the EVM exact scheme. The amount and recipient are part of what the payer signs (an EIP-3009 authorization by default), and the scheme specification limits the facilitator to broadcasting the transaction.
Can Settlens test a facilitator without moving funds?
Yes. It reads GET /supported passively and, with the owner's written authorization, sends one intentionally invalid payload to /verify. It never calls /settle, holds no funds and needs no wallet.