Integration / Start here

Your first x402 integration.

Add payments to an HTTP endpoint or connect a buyer to a paid API. Start with the example for your side of the transaction.

Before you decide anything, paste this. It answers now, and it does not ask who you are:

curl -sS https://facilitator.ultravioletadao.xyz/version

{"version":"2.10.0"}

That is the whole base URL: https://facilitator.ultravioletadao.xyz. There is no key to request and no account to open before the next command works.

You are selling

Your endpoint answers 402 with the terms you accept. The buyer signs one of them and retries with the signature in a header. Your middleware hands that to this facilitator: verify to check it, settle to put it on chain. You never touch a private key, never pay gas, and never wait for a block before answering.

Charging one route is this much code. The route and its price sit in the same file, three lines apart — here, five cents for /world:

// npm install hono @hono/node-server uvd-x402-sdk
import { Hono } from 'hono';
import { serve } from '@hono/node-server';
import { createHonoMiddleware } from 'uvd-x402-sdk';

const app = new Hono();

const paywall = createHonoMiddleware({
  accepts: [{
    network: 'base',
    asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
    amount: '50000',
    payTo: '0xYourWallet',
  }],
});

app.get('/world', paywall, (c) => c.json({ hello: 'world' }));

serve({ fetch: app.fetch, port: 3000 });

The same route in Python, where the price is a decorator on the view:

# pip install flask uvd-x402-sdk
from decimal import Decimal
from flask import Flask, jsonify
from uvd_x402_sdk.integrations import FlaskX402

app = Flask(__name__)
x402 = FlaskX402(app, recipient_address="0xYourWallet")

@app.route("/world")
@x402.require_payment(amount_usd=Decimal("0.05"))
def world():
    return jsonify({"hello": "world"})

The two say the price differently and both are right: the TypeScript middleware takes the on-chain integer, so five cents of a six-decimal USDC is 50000, while the Python decorator takes dollars and converts. Getting that wrong by a factor of a million is the second most common first-integration failure, after the domain name below.

For an axum server the same two calls are the x402-axum crate in this repository, with the middleware applied per route the same way.

The default facilitator in both SDKs is already this one. Nothing to configure until you want a different one.

You are buying

Read the 402, sign the offered network payment and retry with it. Arc uses direct EOA USDC authorizations; native Hedera uses a buyer-signed CryptoTransfer and x402 v2. The facilitator pays network fees. Check /supported for the exact network, asset, version and fee payer.

pip install uvd-x402-sdk
# or, for a reqwest client, the crate:
# x402-reqwest

If your client is an agent rather than a program, the same four calls are MCP tools at /mcp.

Check supported payment options

Not the payment. This one — it is free, it takes no arguments, and it is the only authoritative answer to "can you settle X on Y":

curl -sS https://facilitator.ultravioletadao.xyz/supported

Networks can publish legacy names and CAIP-2 aliases. Arc uses arc/eip155:5042 and arc-testnet/eip155:5042002. Hedera is v2 only, with hedera:mainnet and hedera:testnet. Match the version and network actually advertised. The live table and facilitator accounts are at /networks.

Common integration issues

  • EIP-712 domain names are not uniform. The same stablecoin is "USD Coin" on one chain and "USDC" on another, and the name can flip between a chain's mainnet and its testnet. This is the single most common cause of a first integration failing with "invalid signature". The facilitator already knows the right name for every token it lists, so the fix is to let it resolve rather than to send your own.
  • Timestamps are Unix seconds, not milliseconds. A JavaScript Date.now() passed straight through is a thousand times too large and the authorization is not yet valid for about fifty thousand years.
  • A settle that timed out is not a settle that failed. Retry with the same Idempotency-Key. A fresh unguessable value per payment, reused on every retry of that payment.
  • Not every failure is permanent. A bad signature is; an unreachable RPC is not. Read errorReason before deciding.

All of them, with the field-by-field shapes and worked examples, are in /skill.md — it is written for an agent and reads fine as a manual.

Integration requirements

No SLA, and no support commitment. This is infrastructure a DAO runs and publishes, not a product with a contract behind it. There is no uptime guarantee, no response time, no ticket queue and nobody on call for you. It is free in both senses, and the second one is the part to plan around.

What there is instead: the health endpoint, the live event stream, both settlement counters including the failed one, and every balance the service spends gas from. Judge it on those rather than on a promise.

What happens if it stops. Your settled payments are on chain and do not depend on this service continuing to exist — the chain is the ledger, not us. Unsettled authorizations are just signatures, and their nonces are consumed only on settlement, so nothing is stranded. And the facilitator is not a lock-in: x402 is an open protocol, this implementation is a fork of a public one, and pointing your middleware at a different facilitator is the same one configuration line.

Monitor your integration

whatwhere
Is it up/health
Which release is answering/version
Every verify and settle, as it happens/events/live
Totals, including the failures/stats · /x402
The gas it is spending, per network/networks
The full contract/docs · /openapi.json
The code, and where to open an issuegithub.com/UltravioletaDAO/x402-rs

The routes that answer without a payment

MethodRouteWhat it answersMoves money
GET /health Check facilitator health status no
GET /version Facilitator version and build info no
GET /supported List supported payment schemes and networks no

The compliance route

MethodRouteWhat it answersMoves money
GET /blacklist OFAC sanctioned and blocked addresses no

Try it on a testnet first, and mean it. A settlement is irreversible on every chain here, and the failure modes above are all cheaper to meet on base-sepolia than on Base. The testnet wallets are funded and listed alongside the mainnet ones.