x402 wire format
x402 is Coinbase’s HTTP 402 Payment Required specification. Relaystation implements version 2 to-spec, so standard x402 client libraries work against Baton without modification. This page is the wire reference.
The payment header
A lodestone call carries an X-Payment header: a base64-encoded JSON object holding an EIP-712-signed EIP-3009 TransferWithAuthorization for USDC or EURC.
{
"x402Version": 2,
"accepted": [{
"scheme": "exact",
"network": "base-sepolia",
"asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
"maxAmountRequired": "100000",
"payTo": "0x...",
"resource": {
"url": "https://api.relaystation.ai/v1/baton",
"description": "create a baton"
}
}],
"payload": {
"scheme": "exact",
"authorization": {
"from": "0x...",
"to": "0x...",
"value": "100000",
"validAfter": "0",
"validBefore": "<unix-timestamp>",
"nonce": "0x..."
},
"signature": "0x..."
}
}
Amounts are micros (both USDC and EURC are 6-decimal) — 100000 is $0.10 in USDC, face-value €0.10 in EURC. validBefore is a Unix timestamp a few minutes out; nonce is 32 random bytes.
Signing domain
The signature is an EIP-712 typed-data signature over the EIP-3009 TransferWithAuthorization struct, using the asset contract’s domain (USDC and EURC each have their own EIP-712 domain on each chain):
{
"name": "USD Coin",
"version": "2",
"chainId": "<chain-id>",
"verifyingContract": "<USDC-contract-address>"
}
TransferWithAuthorization(
address from, address to, uint256 value,
uint256 validAfter, uint256 validBefore, bytes32 nonce
)
The success receipt
On success the response is 200/201 with the baton body and a PAYMENT-RESPONSE header — a base64-encoded receipt:
{"success": true, "transaction": "0x...", "network": "eip155:<chainId>", "payer": "0x...", "amount": "100000"}
Settlement is asynchronous: the on-chain transfer is submitted just after your request is admitted, and the transaction hash may be empty in the immediate response while settlement completes. The charge itself is recorded the moment the request is admitted.
Rejection
A payment that fails admission returns 402:
{"x402Version": 2, "error": "PAYMENT_REQUIRED", "errorReason": "<reason>"}
Reasons include replay (the nonce was already used), authorization_expired, authorization_not_yet_valid, invalid_max_amount, invalid_token, merchant_not_configured, and settler_not_configured. The full list is in Errors.
Network
Baton v1 runs on Base Sepolia (testnet) USDC. The asset address above is the Base Sepolia USDC contract. The network field reads base-sepolia for testnet and base for mainnet.