Skip to main content
Base URL: https://x402.semanticpay.io The facilitator verifies and settles x402 payments on behalf of sellers. It currently supports USDT0 on Plasma (eip155:9745) and Stable (eip155:988).

Verify

Validates a payment payload against the seller’s requirements. Called by the seller’s middleware before serving a paid resource.
POST /verify
Request body
FieldTypeDescription
paymentPayloadobjectThe signed payment from the buyer (from the X-PAYMENT header)
paymentRequirementsobjectThe seller’s price and token requirements
Headers
HeaderRequiredDescription
X-Event-CallbackNoURL to receive lifecycle events. The facilitator will POST verify_started and verify_completed (or verify_failed) events to this URL.
{
  "paymentPayload": {
    "network": "eip155:9745",
    "payload": "0x...",
    "scheme": "exact"
  },
  "paymentRequirements": {
    "network": "eip155:9745",
    "maxAmountRequired": "1000000",
    "asset": "0x0000000000000000000000000000000000000001",
    "payTo": "0xSELLER",
    "facilitator": "https://x402.semanticpay.io",
    "scheme": "exact"
  }
}
Response
{
  "isValid": true
}
If invalid, isValid is false and an invalidReason field explains why.

Settle

Settles a verified payment on-chain. Transfers USDT0 from the buyer to the seller via the facilitator’s account.
POST /settle
Request body Same shape as /verify. Headers
HeaderRequiredDescription
X-Event-CallbackNoURL to receive lifecycle events. The facilitator will POST settle_started and settle_completed (or settle_failed) events to this URL.
{
  "paymentPayload": { ... },
  "paymentRequirements": { ... }
}
Response (success)
{
  "success": true,
  "transaction": "0xabc123...",
  "network": "eip155:9745"
}
Response (failure)
{
  "success": false,
  "errorReason": "Insufficient allowance",
  "network": "eip155:9745"
}

Supported

Returns the payment schemes and networks this facilitator supports.
GET /supported
Response
{
  "schemes": [
    {
      "scheme": "exact",
      "network": "eip155:9745"
    },
    {
      "scheme": "exact",
      "network": "eip155:988"
    }
  ]
}

Health

Health check. Returns the facilitator’s address and supported networks.
GET /health
Response
{
  "status": "ok",
  "facilitator": "0xFACILITATOR",
  "networks": [
    {
      "name": "Plasma",
      "network": "eip155:9745",
      "chainId": 9745,
      "usdt0": "0x0000000000000000000000000000000000000001"
    },
    {
      "name": "Stable",
      "network": "eip155:988",
      "chainId": 988,
      "usdt0": "0x..."
    }
  ]
}

Lifecycle Events

The facilitator can push real-time lifecycle events to a callback URL during verification and settlement. This is useful for building UIs that visualize the payment flow as it happens.

How it works

Pass the X-Event-Callback header with a URL on your /verify and /settle requests. The facilitator will POST events to that URL at each stage of the process.
curl -X POST https://x402.semanticpay.io/verify \
  -H "Content-Type: application/json" \
  -H "X-Event-Callback: https://your-server.com/events" \
  -d '{ "paymentPayload": { ... }, "paymentRequirements": { ... } }'
Events are fire-and-forget — they don’t block the verify/settle response. If the callback URL is unreachable, events are silently dropped.

Event format

Each event is a JSON POST with this shape:
{
  "type": "verify_started",
  "step": 6,
  "title": "Payment Verification Started",
  "description": "Facilitator is verifying the payment signature and requirements",
  "details": { ... },
  "actor": "facilitator",
  "timestamp": 1708123456789
}

Event types

Verification events (sent during /verify):
TypeStepDescription
verify_started6Facilitator has begun verifying the payment signature and requirements
verify_completed7Verification finished successfully. details.isValid indicates the result
verify_failed7Verification threw an error. details.error contains the message
Settlement events (sent during /settle):
TypeStepDescription
settle_started9Facilitator is broadcasting the receiveWithAuthorization transaction
settle_completed10Transaction confirmed on-chain. details.transactionHash contains the tx hash
settle_failed10Settlement threw an error. details.error contains the message

Example: receiving events

Set up an endpoint on your server to receive the POSTed events:
app.post("/events", (req, res) => {
  const { type, step, title, details } = req.body;
  console.log(`[step ${step}] ${type}: ${title}`);
  // Forward to SSE clients, WebSocket, etc.
  res.json({ ok: true });
});
Then pass the URL when calling the facilitator:
const response = await fetch("https://x402.semanticpay.io/verify", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-Event-Callback": "https://your-server.com/events",
  },
  body: JSON.stringify({ paymentPayload, paymentRequirements }),
});
If X-Event-Callback is not provided, no events are sent. The facilitator behaves identically — this is purely opt-in.

Errors

All endpoints return standard HTTP status codes.
StatusMeaning
200Success
400Missing required fields (paymentPayload or paymentRequirements)
429Too many requests — rate limit exceeded
500Internal error — the response body contains an error string
Last modified on February 17, 2026