ExchainDocs
DocsAPI

APIx402Settle fees

Settle fees

Settle the fees a guarded Safe owes.

  • Auth Node Token
  • Rate-limited Yes
  • Guide EVM chains
POST
/v1/x402/fees

Settle every fee due with the fee authorization a 402 fee_due returned, signed by the agent over its Safe message hash. In a token without an EIP-3009 a Safe can sign (Ethereum USDT, Polygon USDT0) it is a SafeTx at the Safe’s current nonce, signed over its SafeTx hash, and Exchain sends it as execTransaction. The enclaves co-sign it like a payment and Exchain sends it; it moves exactly what is due to the fee address and nothing else. Fees accrue and settle per token, in the token that was paid. The answer is the wallet’s fee status, with the new settlement pending until it lands.

Authorization

nodeToken
headerAuthorizationBearer <token>

Node Token from the Exchain console. Works for wallets this node registered; the node’s network (preprod or mainnet) decides the network of the request. Use a preprod token in the playground.

Request Body

application/json
  1. body
walletId*WalletId
Match^wal_[0-9A-HJKMNP-TV-Z]{26}$
typedData*

The fee.typedData a 402 fee_due returned. An EIP-3009 TransferWithAuthorization from the Safe to payTo for the amount due or, in a token without an EIP-3009 a Safe can sign (Ethereum USDT, Polygon USDT0), a SafeTx calling the token’s transfer(payTo, amount) at the Safe’s current nonce.

agentSignature*string

The agent’s signature over the Safe message hash, or for a SafeTx the SafeTx hash.

Match^0x[0-9a-f]{130}$

Response Body

Sent. The settlement is pending until the watcher sees it on chain.

application/json
  1. response
walletId*WalletId
Match^wal_[0-9A-HJKMNP-TV-Z]{26}$
charged*boolean

False for a shadow wallet, a licensed node's wallet, or a network without fees.

bps*integer

Basis points of every guarded payment that lands.

settleAt*Amount
Match^[0-9]+$
payTo?EvmAddress
Match^0x[0-9a-fA-F]{40}$
accrued*Amount
Match^[0-9]+$
pending*Amount
Match^[0-9]+$
paid*Amount
Match^[0-9]+$
due*Amount
Match^[0-9]+$
settlements*array<>
assets?array<>

Each governed token’s fees, the first first. Fees accrue and settle in the token that was paid; the top-level amounts are the first token’s.

asOf*string
Match^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z$
Formatdate-time
schemaVersion*string

Wire schema version, "1.1" today.

Value in"1.0""1.1"
chainTip*|null
Example Request
curl -X POST 'https://cosign.exchain.network/v1/x402/fees' \  -H 'Content-Type: application/json' \  -d '{  "walletId": "wal_01M53M3ZNQQ4DDNPE4262QAZ28",  "typedData": {    "domain": {      "name": "USDC",      "version": "2",      "chainId": 84532,      "verifyingContract": "0x036cbd53842c5426634e7929541ec2318f3dcf7e"    },    "types": {      "TransferWithAuthorization": [        {          "name": "from",          "type": "address"        },        {          "name": "to",          "type": "address"        },        {          "name": "value",          "type": "uint256"        },        {          "name": "validAfter",          "type": "uint256"        },        {          "name": "validBefore",          "type": "uint256"        },        {          "name": "nonce",          "type": "bytes32"        }      ]    },    "primaryType": "TransferWithAuthorization",    "message": {      "from": "0x9f2b6c1e4d7a3058b2e6f1c9d4a7b3e5f0c8a216",      "to": "0x1f3e5d7c9b2a4068f1e3d5c7b9a20486e8d1f3a5",      "value": "1000005",      "validAfter": "0",      "validBefore": "1793974327",      "nonce": "0xfd6970eb162fc642aea37658ec7b4ebc985937787aaaa1ac8e01f24a51ba1dd8"    }  },  "agentSignature": "0xa060914fd64b4642914ff62937999ad1821fd430c0342b8993bb90914ec86be24c31f7c48a5cc4391fbf1c86e7f3a752735f23d644782f3fda692fae8e48edae1b"}'
Example Response
{  "walletId": "wal_01M53M3ZNQQ4DDNPE4262QAZ28",  "charged": true,  "bps": 50,  "settleAt": "1000000",  "payTo": "0x1f3e5d7c9b2a4068f1e3d5c7b9a20486e8d1f3a5",  "accrued": "1000005",  "pending": "1000005",  "paid": "0",  "due": "0",  "settlements": [    {      "nonce": "0xfd6970eb162fc642aea37658ec7b4ebc985937787aaaa1ac8e01f24a51ba1dd8",      "amount": "1000005",      "validBefore": 1793974327,      "status": "pending"    }  ],  "assets": [    {      "asset": "eip155:84532/erc20:0x036cbd53842c5426634e7929541ec2318f3dcf7e",      "symbol": "USDC",      "decimals": 6,      "accrued": "1000005",      "pending": "1000005",      "paid": "0",      "due": "0"    }  ],  "asOf": "2026-11-05T14:22:07.318Z",  "schemaVersion": "1.1",  "chainTip": null}

Errors

StatusCodeMeaning
400bad_requestThe body is not JSON or fails the schema; detail names the field.
400fee_mismatchThe authorization is a Permit2 one (detail: "method"), or it does not move exactly what is due from the Safe to the fee address in a governed token (detail names the field, for example amount or payee).
401unauthorizedThe bearer credential is missing, unknown or revoked.
401agent_signature_invalidagentSignature does not recover to the registered agent.
404not_foundThe wallet is not an x402 wallet of this node.
409fee_not_dueThe wallet is not charged, or nothing is due in this token.
409fee_mismatchThe nonce was used before (detail: "nonce_reused"), or a SafeTx is not at the Safe’s current nonce (detail: "safe_nonce").
409fee_unpayableThe Safe cannot pay the fee.
413payload_too_largeThe request body is larger than 64 KiB.
429rate_limitedOver the limit; retry after Retry-After seconds (also in retryAfterSec).
502rpc_failedThe chain could not be read; retry.
502fee_settlement_failedSending the settlement failed; nothing moved.
503quorum_unavailableFewer enclaves reachable than the threshold; retry after Retry-After (5 s).
503x402_unavailableExchain has no RPC for the wallet’s chain.
503unavailabledetail: "record", the audit record could not be written (Retry-After: 5).

Every code and what to do about it: Errors and codes.