> ## Documentation Index
> Fetch the complete documentation index at: https://docs.semanticpay.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Facilitator API

> API reference for the Semantic x402 facilitator.

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

<Card>
  Validates a payment payload against the seller's requirements. Called by the seller's middleware before serving a paid resource.
</Card>

```
POST /verify
```

**Request body**

| Field                 | Type     | Description                                                     |
| --------------------- | -------- | --------------------------------------------------------------- |
| `paymentPayload`      | `object` | The signed payment from the buyer (from the `X-PAYMENT` header) |
| `paymentRequirements` | `object` | The seller's price and token requirements                       |

**Headers**

| Header             | Required | Description                                                                                                                                 |
| ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `X-Event-Callback` | No       | URL to receive lifecycle events. The facilitator will POST `verify_started` and `verify_completed` (or `verify_failed`) events to this URL. |

```json theme={null}
{
  "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**

```json theme={null}
{
  "isValid": true
}
```

If invalid, `isValid` is `false` and an `invalidReason` field explains why.

***

## Settle

<Card>
  Settles a verified payment on-chain. Transfers USDT0 from the buyer to the seller via the facilitator's account.
</Card>

```
POST /settle
```

**Request body**

Same shape as `/verify`.

**Headers**

| Header             | Required | Description                                                                                                                                 |
| ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `X-Event-Callback` | No       | URL to receive lifecycle events. The facilitator will POST `settle_started` and `settle_completed` (or `settle_failed`) events to this URL. |

```json theme={null}
{
  "paymentPayload": { ... },
  "paymentRequirements": { ... }
}
```

**Response (success)**

```json theme={null}
{
  "success": true,
  "transaction": "0xabc123...",
  "network": "eip155:9745"
}
```

**Response (failure)**

```json theme={null}
{
  "success": false,
  "errorReason": "Insufficient allowance",
  "network": "eip155:9745"
}
```

***

## Supported

<Card>
  Returns the payment schemes and networks this facilitator supports.
</Card>

```
GET /supported
```

**Response**

```json theme={null}
{
  "schemes": [
    {
      "scheme": "exact",
      "network": "eip155:9745"
    },
    {
      "scheme": "exact",
      "network": "eip155:988"
    }
  ]
}
```

***

## Health

<Card>
  Health check. Returns the facilitator's address and supported networks.
</Card>

```
GET /health
```

**Response**

```json theme={null}
{
  "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

<Card>
  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.
</Card>

### 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.

```bash theme={null}
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:

```json theme={null}
{
  "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`):

| Type               | Step | Description                                                                |
| ------------------ | ---- | -------------------------------------------------------------------------- |
| `verify_started`   | 6    | Facilitator has begun verifying the payment signature and requirements     |
| `verify_completed` | 7    | Verification finished successfully. `details.isValid` indicates the result |
| `verify_failed`    | 7    | Verification threw an error. `details.error` contains the message          |

**Settlement events** (sent during `/settle`):

| Type               | Step | Description                                                                    |
| ------------------ | ---- | ------------------------------------------------------------------------------ |
| `settle_started`   | 9    | Facilitator is broadcasting the `receiveWithAuthorization` transaction         |
| `settle_completed` | 10   | Transaction confirmed on-chain. `details.transactionHash` contains the tx hash |
| `settle_failed`    | 10   | Settlement threw an error. `details.error` contains the message                |

### Example: receiving events

Set up an endpoint on your server to receive the POSTed events:

```js theme={null}
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:

```js theme={null}
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.

| Status | Meaning                                                             |
| ------ | ------------------------------------------------------------------- |
| `200`  | Success                                                             |
| `400`  | Missing required fields (`paymentPayload` or `paymentRequirements`) |
| `429`  | Too many requests — rate limit exceeded                             |
| `500`  | Internal error — the response body contains an `error` string       |
