x402 payment flow

Payment enforcement happens at the Caddy gateway. The API publishes payment requirements through discovery and OpenAPI; the gateway verifies and settles via the facilitator. An agent may pay on Algorand, on Base, or on both. Paying the Algorand accept is a complete payment. Omitting a Base address does not change rank, eligibility, price, or access.

1. Preflight Call a paid route without PAYMENT-SIGNATURE. Gateway returns 402 with PAYMENT-REQUIRED.
2. Sign Select an accept by network and sign that USDC payment. Algorand (first accept) is a complete payment on its own. Base is optional.
3. Retry Resend the request with PAYMENT-SIGNATURE. Caddy verifies and settles via facilitator.
4. Success Paid route returns 200 and may include PAYMENT-RESPONSE settlement metadata.

Required headers

Choose a payment rail

PAYMENT-REQUIRED lists accepts. Select one by network, not by index. Algorand is first so existing clients keep paying on Algorand. Both accepts use the same price. The payment network is separate from the chain a quote executes on: an Algorand USDC payment can buy a Morpho quote, and a Base USDC payment can buy an Algorand quote.

A Base address is required only when you sign the Base accept or request a Base execution quote. Wallet routes such as /positions, /opportunities/personalized, /eligibility, /plans, and Algorand swaps take an Algorand address alone.

Algorand envelope

{
  "x402Version": 2,
  "scheme": "exact",
  "network": "algorand-mainnet",
  "accepted": { /* selected Algorand accept */ },
  "payload": {
    "paymentGroup": ["<base64-signed-txn>"],
    "paymentIndex": 0
  },
  "paymentRequired": { /* decoded PAYMENT-REQUIRED */ }
}

Base envelope

{
  "x402Version": 2,
  "scheme": "exact",
  "network": "eip155:8453",
  "accepted": { /* selected Base accept */ },
  "payload": {
    "signature": "0x<65-byte EIP-712 signature>",
    "authorization": {
      "from": "0x<payer>",
      "to": "0x<payTo>",
      "value": "10000",
      "validAfter": "<unix seconds>",
      "validBefore": "<unix seconds>",
      "nonce": "0x<32 bytes>"
    }
  },
  "paymentRequired": { /* decoded PAYMENT-REQUIRED */ }
}

Match scheme, network, asset, payTo, and maxAmountRequired from the live accept. Base64-encode the JSON for PAYMENT-SIGNATURE. Full field rules: examples.

Typical accept policy fields

Per-route pricing

Most paid routes default to 0.01 USDC. Wallet-personalized opportunities at /opportunities/personalized cost 0.05 USDC, while /positions?address= costs exactly 0.005 USDC (5000 micro-USDC). Eligibility POST /eligibility costs 0.01 USDC (10000 micro-USDC). Intent compiler POST /plans costs 0.25 USDC (250000 micro-USDC). Policy-as-a-service POST /policy/validate costs 0.25 USDC (250000 micro-USDC). Swap-aware enter compose at POST /execution/compose costs 0.1 USDC (100000 micro-USDC). Claim desk /positions/claimable?address= costs exactly 0.001 USDC (1000 micro-USDC). Batch execution quotes at POST /execution/quotes cost 0.1 USDC flat per request (not per quote item). That price covers a Haystack token launch (mainnet:haystack:v1:launch:token) and a buy of a token still on the bonding curve (mainnet:haystack:v1:buy:bonding). The bonding list at GET /protocols/haystack/launches costs 0.01 USDC. One-token status at GET /protocols/haystack/launches/{tokenNum} is free. Haystack quote and prerequisite opt-in generation are free; only POST /swaps/transactions costs 0.005 USDC. Discovery x402 metadata exposes both amountUsdc and amountMicro; Caddy PAYMENT-REQUIRED uses micro-USDC. See the endpoint catalog for current values from discovery metadata.

Walletless swaps

  1. Request a free POST /swaps/quote using integer asset base units.
  2. Call free POST /swaps/optin. If it returns transactions, sign and submit them locally, wait for confirmation, then request a fresh quote.
  3. Preflight paid POST /swaps/transactions, satisfy its 0.005 USDC x402 requirement, and retry with PAYMENT-SIGNATURE.
  4. Sign only the returned userSignIndexes, preserve any pre-signed members and atomic-group order, then submit the complete group through your own Algod client.

1) Free quote

curl -i https://canix402-api.compx.io/swaps/quote \
  -H 'content-type: application/json' \
  -d '{
    "address": "YOUR_ALGORAND_ADDRESS",
    "fromAssetId": 0,
    "toAssetId": 31566704,
    "amount": "1000000",
    "type": "fixed-input"
  }'

2) Free opt-in

curl -i https://canix402-api.compx.io/swaps/optin \
  -H 'content-type: application/json' \
  -d '{
    "address": "YOUR_ALGORAND_ADDRESS",
    "quote": { /* full data object from /swaps/quote */ }
  }'

3) Paid transactions — preflight then retry

curl -i https://canix402-api.compx.io/swaps/transactions \
  -H 'content-type: application/json' \
  -d '{
    "address": "YOUR_ALGORAND_ADDRESS",
    "quote": { /* fresh quote data object */ },
    "slippage": 0.005
  }'

curl -i https://canix402-api.compx.io/swaps/transactions \
  -H 'content-type: application/json' \
  -H 'PAYMENT-SIGNATURE: <base64-json-payload>' \
  -d '{
    "address": "YOUR_ALGORAND_ADDRESS",
    "quote": { /* fresh quote data object */ },
    "slippage": 0.005
  }'

Quotes are short-lived. Canix402 never receives wallet keys and never submits opt-ins or swaps. The x402 access charge is separate from Haystack's SDK-default 10 bps output fee (including its referral split), DEX fees, route price impact, and Algorand network fees. Sample payloads: examples.

MCP server (agent tools)

Agents can connect to the remote canix402 MCP endpoint instead of calling HTTP endpoints directly. The MCP layer is walletless: paid tools return payment requirements first, then accept a caller-supplied paymentSignature on retry.

Full setup, tool list, and paid-tool flow: MCP documentation.

{
  "mcpServers": {
    "canix402": {
      "url": "https://canix402-mcp.compx.io/mcp"
    }
  }
}

Common failure modes

curl -i https://canix402-api.compx.io/opportunities