Q402 Developer Docs
Everything you need to add gasless USDC payments to your product. One API, wallet-authenticated trial access, and zero gas for your users across live relay chains, plus Avalanche beta access by inquiry.
Overview
Q402 is a gasless transaction relay for EVM chains. Your users send USDC without ever needing BNB, ETH, or OKB for gas on live relay chains. You integrate one API. The rest is invisible. Avalanche is available as a beta onboarding track by inquiry.
What is an API?
An API is just a URL your server calls. Like ordering food at a restaurant — you send a request ("here's a user's signed transaction"), Q402's server handles the work, and sends back a result ("done, txHash: 0xabc..."). No blockchain expertise needed on your end.
How It Works
Three actors. One transaction. Zero gas for your users on live relay chains, with Avalanche beta requests handled manually.
Quick Start
Get your first gasless transaction running in under 5 minutes.
0 · Start the free trial
// From the dashboard
// 1. Connect your wallet
// 2. Click "Authenticate Wallet"
// 3. Sign the challenge message
// 4. Copy the current trial API key to your backend only1 · Load the SDK
<script src="https://q402.io/q402-sdk.js"></script>2 · User signs (client-side, zero gas)
const q402 = new Q402Client({
chain: "bnb", // "bnb" | "eth" | "xlayer"
});
const prepared = await q402.preparePayment({
to: recipientAddress,
amount: "50",
token: "USDC",
});
// Send "prepared" to your backend. Do not store your API key in the browser.
3 · Submit from your backend
// POST to Q402 relay — Q402 handles the rest
const res = await fetch("https://q402.io/api/relay", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
apiKey: process.env.Q402_API_KEY,
...prepared,
}),
});
const data = await res.json();
// { success: true, txHash: "0xabc123...", chain: "bnb", blockNumber: "38482910" }Gas Pool
Q402 uses a gas pool model for live relay chains. You deposit native tokens (BNB, ETH, OKB) into the Q402 relayer address shown in the dashboard. Every relayed transaction debits actual native gas from the wallet-linked tank.
Send native tokens (BNB / ETH / OKB) to the relayer address shown in your dashboard. Balances are tracked against the wallet that authenticated the current trial key.
Before broadcast, Q402 estimates the native gas cost for the specific chain, applies a safety margin, and rejects the relay if your tank would fall short. Successful relays deduct the actual gas cost afterward.
After sending funds, paste the native transfer transaction hash into the dashboard to claim the deposit. Self-serve withdrawals are currently disabled while the safer flow is being rebuilt.
Authentication
All relay requests require your API key in the apiKey field of the request body. Keep that key on your backend only. Trial access is wallet-authenticated: connect your wallet in the dashboard, request a challenge, sign it, and reveal the current API key for that wallet.
// POST /api/auth/challenge
{
"address": "0xYourWallet..."
}
// Response
{
"message": "Sign this message to start your Q402 free trial. ...",
"expiresIn": 600
}// POST /api/keys/provision
{
"address": "0xYourWallet...",
"signature": "0xSignedChallenge..."
}
// Response
{
"apiKey": "q402_live_YOUR_API_KEY",
"plan": "trial",
"isNew": true
}// POST /api/relay
{
"apiKey": "q402_live_YOUR_API_KEY",
"chain": "bnb",
"token": "USDC",
...
}// POST /api/gas-tank/verify-deposit
{
"apiKey": "q402_live_YOUR_API_KEY",
"chain": "bnb",
"txHash": "0xDepositTransactionHash..."
}API Reference
Base URL: https://q402.io/api
Generate a short-lived challenge message for a wallet. The client signs the returned message with personal_sign.
Verify the signed challenge and reveal the current API key for that wallet, or provision a new trial key if none exists yet.
Submit a signed EIP-712 + EIP-7702 payload. Q402 verifies the signature and relays the transaction on-chain using your gas pool.
// Request body
{
"apiKey": "q402_live_YOUR_API_KEY",
"chain": "bnb", // bnb | eth | xlayer
"token": "USDC", // USDC | USDT
"from": "0xUserWallet...",
"to": "0xRecipient...",
"amount": "50000000", // atomic units (6 decimals = 50 USDC)
"nonce": "0", // sequential user nonce in delegated storage
"deadline": 1751289600,
"witnessSig": "0xabc123...",
"authorization": { ... } // EIP-7702 authorization object
}
// Response 200
{
"success": true,
"txHash": "0xdef456...",
"chain": "bnb",
"blockNumber": "54540550",
"tokenAmount": 50,
"gasCostNative": 0.000021,
"method": "eip7702"
}
// Response 402
{
"code": "GAS_TANK_INSUFFICIENT",
"error": "Insufficient gas tank on eth. Deposit more native gas before relaying this payment.",
"chain": "eth",
"availableBalanceNative": "0.00031",
"estimatedGasNative": "0.00041",
"requiredBalanceNative": "0.00075",
"recommendedTopUpNative": "0.00044"
}Claim a native-token gas deposit with the exact transaction hash. The sender wallet must match the wallet linked to the provided API key.
// Request body
{
"apiKey": "q402_live_YOUR_API_KEY",
"chain": "bnb",
"txHash": "0xDepositTransactionHash..."
}
// Response 200
{
"credited": true,
"message": "Deposit claimed and credited to your gas tank.",
"balances": {
"bnb": 0.125
},
"deposit": {
"chain": "bnb",
"token": "BNB",
"amount": 0.125,
"txHash": "0xDepositTransactionHash..."
}
}Returns the relayer (facilitator) wallet address. Required for SignatureBasedExecutorV2 signing on every live 7702 chain (`bnb`, `eth`, `xlayer`) — include this address in your EIP-712 payload before submitting.
// GET /api/relay/info
{ "facilitator": "0xRelayerAddress..." }Chain Support
Same API and signing model across live relay chains. Avalanche stays visible as a beta onboarding path, but it does not use the standard Q402 self-serve relay flow today.
| Chain | chain param | Chain ID | Status | Avg gas/tx |
|---|---|---|---|---|
BNB Chain | bnb | 56 | Mainnet Live | ~$0.001 |
Ethereum | eth | 1 | Mainnet Live | ~$0.19 |
X Layer | xlayer | 196 | Mainnet Live | ~$0.001 |
Avalanche | avax | 43114 | Beta | Inquiry only |
Arbitrum | arbitrum | 42161 | Coming Soon | — |
Scroll | scroll | 534352 | Coming Soon | — |
EIP-712 Signing
Q402 uses EIP-712 typed structured data signing — the same standard used by Uniswap, Compound, and major DeFi protocols. The user signs a human-readable message. No gas. No blockchain interaction.
Domain Separator
// Contract addresses per chain
const CONTRACTS = {
bnb: "0x2Eb0c999Ac01098Da44763Aa7E87479d905ecdC7",
eth: "0x2Eb0c999Ac01098Da44763Aa7E87479d905ecdC7",
xlayer: "0xf3eDaCAa8A247B8B8F898FAFA5AEd8E161ADc72a",
};
// SignatureBasedExecutorV2 uses a fixed domain across live chains
const domain = {
name: "SignatureBasedExecutorV2",
version: "2",
chainId: 56, // 1=ETH, 56=BNB, 196=X Layer
verifyingContract: CONTRACTS.bnb,
};Type Definition
const types = {
TransferAuthorization: [
{ name: "owner", type: "address" },
{ name: "facilitator", type: "address" },
{ name: "token", type: "address" },
{ name: "recipient", type: "address" },
{ name: "amount", type: "uint256" },
{ name: "nonce", type: "uint256" },
{ name: "deadline", type: "uint256" },
],
};Signing with ethers.js
const signature = await signer.signTypedData(domain, types, {
owner: userAddress,
facilitator: relayInfo.facilitator,
token: usdcAddress,
recipient: recipientAddress,
amount: ethers.parseUnits("50", 6),
nonce: currentNonce,
deadline: Math.floor(Date.now() / 1000) + 3600,
});Error Codes
Errors currently return an HTTP status plus a JSON body with a stable code and human-readable error. Handle the status code first, branch on code, and log or surface the message string.
FAQ
Ready to start the free trial?
Connect your wallet, sign the challenge, and reveal your current API key without leaving the dashboard.