---
title: "x402 facilitator testing: /supported and /verify | Settlens"
description: "Check that your x402 facilitator advertises valid V2 capabilities and signers, covers the terms resources advertise, and rejects forged signatures at /verify."
url: https://settlens.com/use-cases/facilitators
last_updated: 2026-10-13
---

# Test your x402 facilitator without moving funds

> **In short:** Settlens tests an x402 facilitator without moving funds: it checks the GET /supported response, cross-checks it against the terms resources advertise and, with the operator's authorization, confirms that POST /verify rejects an intentionally invalid signature. It never calls /settle and needs no wallet or payment key.

For operators of x402 facilitators. Settlens reads GET /supported, checks it against the terms resources actually advertise and, with your authorization, confirms that /verify rejects an invalid signature. It never calls /settle.

[Request a pilot](https://settlens.com/contact) [See what Settlens sends](https://settlens.com/use-cases/facilitators#what-settlens-sends)

Real output from the bundled demo, whose /facilitator-accept route is built to accept any signature.

**Authorized /verify probe**

```text
$ settlens scan http://127.0.0.1:4402/secure \
    --facilitator http://127.0.0.1:4402/facilitator-accept \
    --active --authorized --authorization-ref PILOT-FAC-001 --no-write
Settlens x402 assessment f6968418
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
```

## Who this is for

You operate the service that x402 resource servers call to check and execute payments: `GET /supported` advertises the kinds, extensions and signers you handle, `POST /verify` says whether a payment payload is valid, and `POST /settle` executes it on chain.

Resource servers serve paid content based on your `isValid` answer. One verification bug becomes a payment bypass for every merchant that relies on you, and those merchants need a way to check your behavior without taking your word for it. Our guide to [x402 facilitator security](https://settlens.com/learn/x402-facilitator-security) covers what each endpoint must and must not do.

## What goes wrong on a facilitator

Each failure mode maps to a check Settlens runs. The tag on each card is the check id you will see in reports.

- **/verify accepts a forged signature**

  During an authorized probe, Settlens posts an intentionally invalid payload to /verify (an all-zero signature on EVM networks). isValid=true is a critical verification bypass.

  security.facilitator_rejects_invalid_signature

- **/verify answers in a non-standard shape**

  Resource servers decide from isValid. An answer without a boolean isValid field risks being misread as success.

  facilitator.verify_response_schema

- **/supported breaks the core shape**

  kinds must be a non-empty array with x402Version, scheme and network (CAIP-2 for V2 kinds), extensions an array of strings, and signers a map of networks to address lists.

  facilitator.supported_schema

- **No x402 V2 capability**

  A facilitator without at least one kind with x402Version 2 cannot verify or settle V2 payments, whatever else it advertises.

  facilitator.v2_capability

- **Resources advertise what you cannot settle**

  Every scheme and network pair a resource advertises must appear in your kinds for the same x402Version, or clients sign payments that can never be verified.

  facilitator.requirement_coverage

- **Signer metadata is missing**

  Each advertised network needs a non-empty signer list, for the exact network or its namespace wildcard such as eip155:\*.

  facilitator.signer_coverage

- **Capabilities over weak transport**

  Settlens flags plain HTTP outside loopback, a non-JSON media type, duplicate kinds and responses above the 1 MiB evidence limit.

  facilitator.https

## What Settlens sends, and what it never sends

The passive part reads public metadata. The active part is opt-in, needs an authorization reference and sends one invalid payload built from the resource's first advertised requirement.

_Diagram: Sequence between Settlens, a paid resource and a facilitator. Passive: Settlens sends a GET without payment to the resource and receives 402 with PAYMENT-REQUIRED, then sends GET /supported to the facilitator and receives kinds, extensions and signers. Authorized only: Settlens sends an invalid PAYMENT-SIGNATURE to the resource, which must not answer 2xx, and posts the invalid payload to /verify, which must answer isValid false. /settle is never called._

_For EVM networks the invalid payload carries an all-zero signature; for Solana, an all-zero transaction. The probe needs no wallet or payment key._

## The Settlens workflow for facilitators

Start with your public capabilities, then cross-check them against a resource that uses you, then prove /verify fails closed.

1. **Scan GET /supported**

   `settlens facilitator https://facilitator.example.com` checks reachability, HTTP 200, the JSON media type, HTTPS, the response size, the SupportedResponse schema, V2 capability and duplicate kinds.

2. **Cross-check a resource that uses you**

   `settlens scan <resource-url> --facilitator <base-url>` adds coverage: every advertised scheme and network must be in your kinds, and every advertised network needs signers.

3. **Prove /verify fails closed**

   Add `--active --authorized --authorization-ref <ticket>`. Settlens posts one invalid payload to `/verify` and checks that `isValid` is a boolean and is `false`.

4. **Gate releases and publish evidence**

   Run the same configuration in CI on every change, then sign the report with an ed25519 key so integrators can verify it offline. See [evidence](https://settlens.com/docs/evidence).

**settlens.config.json (illustrative values)**

```json
{
  "version": 1,
  "failOn": "high",
  "targets": [
    {
      "name": "reference-resource",
      "url": "https://api.staging.example.com/v1/forecast",
      "facilitator": {
        "name": "staging-facilitator",
        "url": "https://facilitator.staging.example.com",
        "timeoutMs": 8000,
        "headers": {
          "Authorization": "Bearer ${FACILITATOR_TOKEN}"
        }
      }
    }
  ]
}
```

**CI run with the authorized probe**

```shell
settlens check --config settlens.config.json \
  --allow-host facilitator.staging.example.com \
  --active --authorized --authorization-ref CHG-2291
```

> **Secrets stay out of reports**
>
> `${FACILITATOR_TOKEN}` is expanded from the environment when the configuration loads and is never written to a report. Custom headers are refused unless their host is allowlisted with `--allow-host` or the Action's `allowed-hosts` input.

## What the findings look like

Real output from the bundled demo. One facilitator covers the resource, one advertises only Base mainnet while the resource asks for Base Sepolia, and the offline verifier gives a second opinion on the all-zero signature.

**GET /supported only**

```text
$ settlens facilitator http://127.0.0.1:4402/facilitator --no-write
Settlens x402 assessment 41fa3ca8
Targets 1 · Active 0 · Settlement calls 0
 
127.0.0.1  GET http://127.0.0.1:4402/facilitator/supported
8 pass · 0 fail · 0 warn · 0 skip
 
Total: 8 pass · 0 fail · 0 warn · 0 skip
```

**Coverage gap**

```text
$ settlens scan http://127.0.0.1:4402/secure \
    --facilitator http://127.0.0.1:4402/facilitator-empty --no-write
Settlens x402 assessment 7047aa73
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
```

### A second opinion on your verifier

`settlens verify-payment payment.json` takes a requirement and a captured payload. For EIP-3009 authorizations of the `exact` EVM scheme it rebuilds the EIP-712 domain from the requirement, recovers the EIP-3009 signer and checks recipient, amount and the validity window, with no RPC. For Solana it checks the ed25519 signature in every signer slot and reports your fee-payer slot as pending until you sign it at settlement.

Run it on payloads your `/verify` accepted or rejected and compare the answers. Here it rejects the same all-zero signature the active probe sends. See [Verify](https://settlens.com/product/verify), and the [EIP-3009 explainer](https://settlens.com/learn/eip-3009) for how the authorization and its EIP-712 domain are built.

**Offline signature check of the invalid payload**

```text
$ settlens verify-payment payment.json --now 2026-10-13T10:00:00Z
REJECTED exact EVM payment authorization
Signature valid:  false
Recipient bound:  true
Amount bound:     true
Within window:    true (at 1791885600)
Reasons:
  - Signature verification failed: invalid signature r: out of range 1..Point.Fn.ORDER
```

## Facilitator checks

Generated from the Settlens check catalog. Coverage and signer checks need a resource target; /verify checks need the authorized active probe.

_Checks on an x402 facilitator_

| Check | What Settlens verifies | Severity |
| --- | --- | --- |
| `facilitator.reachable` ; Facilitator /supported is reachable | GET \<facilitator>/supported returned an HTTP response within the timeout. Redirects are not followed. | high |
| `facilitator.response_body_limit` ; Facilitator capability response fits the evidence limit | The /supported response is at most 1 MiB. | high |
| `facilitator.supported_status` ; Facilitator exposes capabilities successfully | GET /supported returned HTTP 200. | high |
| `facilitator.content_type` ; Facilitator capabilities use a JSON media type | The /supported Content-Type is application/json or another +json media type. | medium |
| `facilitator.https` ; Facilitator capability transport is protected | The facilitator URL uses HTTPS, or loopback HTTP for local testing. | medium |
| `facilitator.supported_schema` ; SupportedResponse matches the x402 core shape | 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. | high |
| `facilitator.v2_capability` ; Facilitator advertises x402 V2 capabilities | At least one supported kind has x402Version 2. | high |
| `facilitator.duplicate_kinds` ; Facilitator capabilities are unambiguous | No x402Version, scheme and network combination appears twice in kinds. | low |
| `facilitator.requirement_coverage` ; Facilitator covers advertised payment requirements | 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. | high |
| `facilitator.signer_coverage` ; Facilitator publishes 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:\*). | medium |
| `facilitator.verify_reachable` ; Facilitator /verify is 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. | medium |
| `facilitator.verify_response_schema` ; Facilitator /verify returns a conformant VerifyResponse | The /verify answer to the intentionally invalid payload is a JSON object with a boolean isValid field. | high |
| `security.facilitator_rejects_invalid_signature` ; Facilitator /verify rejects an invalid signature | /verify returns isValid=false for the intentionally invalid, all-zero signature. Settlens never calls /settle. | critical |

See the [facilitator checks in the check reference](https://settlens.com/docs/checks#facilitator-checks) for why each check matters and how to fix it, and the [methodology](https://settlens.com/docs/methodology) for what a result proves.

## What you get

- **Capability reports**

  JSON with a SHA-256 integrity block, HTML and SARIF for every /supported scan. settlens facilitator keeps the validated /supported response, signer addresses included; a resource scan keeps the kinds, extensions and signer networks.

  [Report format](https://settlens.com/docs/reports)

- **Fail-closed evidence**

  A report in active-authorized mode that records your authorization reference, zero settlement calls and zero private keys used.

  [Assess](https://settlens.com/product/assess)

- **A release gate**

  Run the same configuration on every change to your facilitator and fail the build on a high or critical finding.

  [CI gate](https://settlens.com/product/ci)

- **Evidence for integrators**

  Signed attestations that merchants and auditors can verify offline, without trusting your infrastructure.

  [How auditors use it](https://settlens.com/use-cases/security-teams)

## Limits to keep in mind

> **Settlement is out of scope**
>
> Settlens never calls /settle, never submits or broadcasts a transaction and never moves funds. It does not test on-chain execution, gas handling, nonce use or replay protection.

- The `/verify` probe sends one class of invalid payload. It shows that your facilitator refuses an all-zero signature, not that it handles every malformed or malicious payload.
- The probe is built from a resource's advertised requirement, so it needs a resource target that names your facilitator.
- Signer coverage checks that signer lists are published, not that the addresses are yours or funded.
- `verify-payment` checks signatures and binding offline. It does not check balances, on-chain nonce use or settlement, and it covers EIP-3009 authorizations of the `exact` EVM scheme (not Permit2 or ERC-7710 payloads) and Solana transaction signatures.

## Questions from facilitator operators

**Does Settlens ever call /settle?**

No. No Settlens command or MCP tool calls /settle. Reports record the number of settlement calls, which is always zero.

**Do you need our keys or a funded wallet?**

No. The passive scan reads public metadata and the active probe sends an invalid payload that needs no signing key. Settlens never holds wallets, payment keys or funds.

**Can we test /supported without a resource server?**

Yes. settlens facilitator \<base-url> checks /supported on its own. Coverage, signer and /verify checks need a resource that advertises requirements, such as your own test resource.

**Is the /verify probe safe to run against production?**

It sends a single payload that a correct facilitator rejects, and it only runs with --active, --authorized and an authorization reference. Run it with the operator's explicit approval, and start on staging.

**Which networks are covered?**

Schema and coverage checks work on any CAIP-2 network. Offline signature verification covers EIP-3009 authorizations of the exact scheme on eip155 networks and the signers of Solana transactions.

## Show integrators your facilitator fails closed

A pilot covers your /supported endpoint, one reference resource and an authorized /verify probe, and ends with signed evidence.

[Request a pilot](https://settlens.com/contact) [Read the security model](https://settlens.com/docs/security)

## Sources

1. [x402 protocol specification, version 2 (§5.4 VerifyResponse, §7 facilitator interface)](https://github.com/x402-foundation/x402/blob/main/specs/x402-specification-v2.md) — x402 Foundation
2. [Scheme exact on EVM: EIP-3009 authorization payload and verification](https://github.com/x402-foundation/x402/blob/main/specs/schemes/exact/scheme_exact_evm.md) — x402 Foundation
3. [EIP-3009: Transfer With Authorization](https://eips.ethereum.org/EIPS/eip-3009) — Ethereum Improvement Proposals
4. [EIP-712: Typed structured data hashing and signing](https://eips.ethereum.org/EIPS/eip-712) — Ethereum Improvement Proposals
5. [CAIP-2: Blockchain ID specification](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-2.md) — Chain Agnostic Standards Alliance
