April 02, 2026

RFC: risk_check_url for x402

This is a proposal for adding optional counterparty risk verification to the x402 payment protocol. The goal: any agent, any framework, any facilitator can verify counterparty trust before committing funds.

The problem

x402 defines a clean payment flow. An agent requests a resource, gets a 402 Payment Required response with payment details, signs a USDC transaction, and the facilitator verifies it. The resource is served.

What x402 does not define is whether the agent should pay at all. The protocol tells the agent how to pay. It does not tell the agent whether the counterparty is trustworthy.

Today, agents pay blindly. They see a 402 header, they pay. No verification, no risk assessment, no pause. This works when every x402 endpoint is operated by known, trusted parties. It breaks the moment the ecosystem opens up to unknown operators.

The proposal: risk_check_url

Add an optional risk_check_url field to the x402 discovery document (/.well-known/x402.json). This URL points to a risk scoring endpoint that agents can call before paying.

// /.well-known/x402.json (extended)
{
  "version": 1,
  "endpoints": ["/v1/score"],
  "payment": {
    "network": "eip155:8453",
    "currency": "USDC",
    "facilitator": "https://x402.org/facilitator"
  },
  "risk_check_url": "https://revettr.com/v1/score"
}

How it works

When an agent encounters a 402 Payment Required response:

  1. Agent extracts the payment recipient wallet address from the 402 header
  2. Agent extracts the service domain from the request URL
  3. Agent calls the risk_check_url with the wallet address and domain
  4. The risk check endpoint returns a score (0 to 100), tier, and flags
  5. Agent decides whether to proceed based on its risk tolerance threshold
# Agent-side flow (pseudocode)

response = http.get("https://api.example.com/data")

if response.status == 402:
  payment = parse_x402_header(response)
  risk = http.post(risk_check_url, {
    "wallet_address": payment.recipient,
    "domain": "api.example.com"
  })

  if risk.score >= agent.min_trust_score:
    sign_and_pay(payment)
  else:
    log(f"Declined: {risk.tier} risk, flags={risk.flags}")
    skip()

Request format

The risk check endpoint accepts a JSON POST with any combination of counterparty identifiers:

POST /v1/score
Content-Type: application/json

{
  "wallet_address": "0xabc...",
  "domain": "api.example.com",
  "ip": "104.18.28.72",
  "company_name": "Example Corp"
}

More fields means higher confidence. At minimum, provide the wallet address (always available from the 402 header).

Response format

{
  "score": 85,
  "tier": "low",
  "confidence": 0.6,
  "flags": ["wallet_contract_active", "wallet_established"],
  "signal_scores": {
    "wallet": {"score": 85, "available": true},
    "domain": {"score": 90, "available": true}
  }
}
FieldTypeDescription
scoreint (0 to 100)Composite risk score. Higher is safer.
tierstringlow (80 to 100), medium (60 to 79), high (30 to 59), critical (0 to 29)
confidencefloat (0 to 1)How many signal groups were available
flagsstring[]Specific risk signals triggered
signal_scoresobjectPer-signal breakdown for transparency

Discovery endpoint

Risk check providers expose a discovery endpoint at /.well-known/risk-check.json:

// GET /.well-known/risk-check.json
{
  "name": "Revettr",
  "version": "0.1.0",
  "endpoint": "/v1/score",
  "method": "POST",
  "pricing": {
    "amount": "0.01",
    "currency": "USDC",
    "protocol": "x402"
  },
  "signals": ["wallet", "domain", "ip", "sanctions", "erc8004"],
  "chains_supported": ["base", "ethereum", "optimism", "arbitrum"],
  "response_schema": "/docs#/ScoreResponse"
}

Design principles

Reference implementation

Revettr implements this pattern today:

# pip install revettr
from revettr import Revettr

client = Revettr()
score = client.score(
  wallet_address="0xabc...",
  domain="api.example.com"
)

if score["score"] >= 70:
  proceed_with_payment()
else:
  decline_transaction(reason=score["flags"])

Live at revettr.com/v1/score. $0.01 USDC per check via x402. Discovery at /.well-known/risk-check.json.

The x402 ecosystem is building the payment layer. This RFC proposes the trust layer that sits alongside it. We welcome other implementations.

← All posts