ConceptsFacilitators

Facilitators

A facilitator is a stateless service that verifies and settles x402 payment headers on behalf of sellers. The seller forwards the buyer’s signed X-PAYMENT to the facilitator’s POST /settle; the facilitator checks the signature, confirms the buyer’s USDC balance covers the amount, broadcasts the EIP-3009 transaction (in exact mode) or calls Permit2 (in upto mode), and returns the on-chain tx hash.

What facilitators do

For each settled payment:

  1. Verify: recover the signer from the EIP-712 signature; check it matches the from address in the authorization
  2. Check funds: read on-chain USDC balance for from; reject if insufficient
  3. Settle: broadcast the transferWithAuthorization (exact) or call Permit2 (upto)
  4. Return: respond { success: true, txHash: "0x...", payer: "0x...", network: "eip155:..." }

Sellers don’t need to run a node, hold gas, or know how to broadcast. The facilitator absorbs that.

Choosing a facilitator

OptionWhenTrade-offs
Public (x402.org/facilitator)Demos, dev, low volumeFree; rate-limited; no SLA
Self-hostedProduction, high volume, regulatory needsYou run it; you pay gas; you own the SLA
Provider-hostedProduction with ops handed offPaid; SLA; pick one with the schemes + chains you need

For most starting integrations, x402.org’s public facilitator is the right pick. Move to self-hosted or a provider when:

  • Rate limits bite (you hit 429s during normal traffic)
  • You need a specific chain or scheme the public facilitator doesn’t support
  • Compliance requires a known legal entity in the settlement path
  • You want gas-sponsorship economics under your control

Multi-facilitator failover

Set AGENTAGON_FACILITATOR_URLS=url1,url2,url3 to give the seller middleware a pool. On a transient 5xx or timeout, the middleware retries the same facilitator three times with exponential backoff; on exhaustion it falls back to the next URL. The buyer sees one fresh 402 challenge if the whole pool is exhausted.

import os
os.environ["AGENTAGON_FACILITATOR_URLS"] = (
    "https://x402.org/facilitator,"
    "https://my-backup.example.com/facilitator"
)

The pool is process-wide; configure it once at startup. The middleware doesn’t load-balance proactively; it just falls over on failure.

Permit2 and upto

upto payments use Permit2 to let the facilitator pull a variable amount from the buyer’s wallet (up to the maxAmountRequired). This requires:

  • A one-time Permit2 allowance from the buyer’s wallet to the facilitator’s on-chain caller (set via Permit2.approve(facilitator_address, USDC, max_uint, deadline))
  • The seller advertising upto in its 402’s accepts[] with the facilitator’s on-chain address in extra.facilitatorAddress
⚠️

Public testnet facilitators (including x402.org’s) don’t yet ship gas-sponsoring extensions. Each buyer wallet must approve Permit2 once on-chain. See docs/EXTERNAL_GAPS.md EG-1 for the full status.

If you don’t need upto, stay on exact. EIP-3009 is gas-sponsored by the facilitator’s on-chain settlement; buyers don’t hold gas.

Settlement timing

The facilitator response includes txHash but the on-chain transaction is broadcast asynchronously. The seller can return 200 to the buyer immediately on success: true; the tx confirms within seconds on Base. If you need on-chain finality before responding (e.g. for fraud-sensitive flows), poll the tx hash; otherwise trust the facilitator’s verification.

See also