x402 Documentation

Wallet setup, SDK integration, MCP server configuration, and complete API reference.

🔑 Prerequisites

x402 uses USDC on Solana mainnet for payments. You need:

Requirement Details
Solana Keypair A JSON file containing your private key (Solana CLI format)
USDC Balance Minimum 0.01 USDC on Solana mainnet
SOL Balance ~0.005 SOL for transaction fees (~$0.01)
Node.js v18+ (for SDK and MCP server)
No accounts, no API keys. x402 is fully permissionless. Your Solana wallet IS your identity. The SDK auto-signs USDC transfers when a 402 response is received.

💳 Wallet Setup

Create a Solana keypair and fund it with USDC. The SDK uses this to auto-sign payment transactions.

1. Create Keypair
# Install Solana CLI (if not installed)
$ sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)"

# Create a new keypair
$ solana-keygen new -o ~/akca-wallet.json

# View your public address
$ solana address -k ~/akca-wallet.json
FgTmb5SQnSyG16jFVwEnPZHDPZjgoTnsdmbCAAGCoCSL
2. Fund with USDC
# Get USDC on Solana mainnet via:

Option A: DEX
  Swap SOL → USDC on Jupiter (jup.ag) or Raydium

Option B: CEX
  Buy USDC on Coinbase/Binance, withdraw to Solana address

Option C: Bridge
  Bridge USDC from Ethereum/Polygon via Wormhole or Allbridge

# USDC contract on Solana:
EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
3. Load in Code
import { Keypair } from '@solana/web3.js';
import { readFileSync } from 'fs';

// From Solana CLI keypair file (recommended)
const secret = JSON.parse(
  readFileSync('~/akca-wallet.json', 'utf8')
);
const wallet = Keypair.fromSecretKey(
  new Uint8Array(secret)
);

// Or from base58 private key string
import bs58 from 'bs58';
const wallet2 = Keypair.fromSecretKey(
  bs58.decode(process.env.SOLANA_PRIVATE_KEY)
);
Security: Never commit your keypair file to git. Use environment variables or a secrets manager in production. The keypair file contains your private key — anyone with it can spend your USDC.

📦 SDK Installation

The npm SDK handles 402 responses, USDC payments, and session cookies automatically.

Install
$ npm install @akcanetwork/x402 @solana/web3.js @solana/spl-token
Initialize
import { AkcaX402Client } from '@akcanetwork/x402';
import { Keypair } from '@solana/web3.js';
import { readFileSync } from 'fs';

const secret = JSON.parse(readFileSync('~/akca-wallet.json', 'utf8'));
const wallet = Keypair.fromSecretKey(new Uint8Array(secret));

const akca = new AkcaX402Client({
  wallet,
  // baseUrl: 'https://api.akca.network' (default)
  // rpcUrl: 'https://api.mainnet-beta.solana.com' (default)
});
Parameter Type Default Description
wallet Keypair required Solana keypair for signing USDC payments
baseUrl string https://api.akca.network API server URL
rpcUrl string Solana mainnet Custom Solana RPC endpoint

🌐 Proxy — Zero Setup

Proxy requires no local installation. Requests are routed server-side through Akca exit nodes. No WireGuard, no tunnels — just HTTP calls.

Per-Request Proxy (0.001 USDC/req)
// Route a request through German exit node
const result = await akca.fetch(
  'https://api.example.com/data',
  { country: 'DE', method: 'GET' }
);

// SDK flow: request → 402 → auto-pay USDC → retry → 200
console.log(result.status); // 200
console.log(result.body); // response body
Session Proxy (1.00 USDC/24h, unlimited requests)
// Create 24h session — pay once, unlimited requests
await akca.createProxySession({ country: 'US' });

// All subsequent requests use the session cookie (no re-payment)
const r1 = await akca.fetch('https://site1.com'); // free
const r2 = await akca.fetch('https://site2.com'); // free
const r3 = await akca.fetch('https://site3.com'); // free
When to use Proxy: API scraping, geo-restricted content, bot requests. Under 500 requests/day → per-request is cheaper. Over 500 → buy a session.

🛡 VPN — WireGuard Tunnel

Full device VPN via WireGuard or AmneziaWG (DPI obfuscation). The SDK can auto-install WireGuard and manage the tunnel lifecycle.

One-Liner: quickVpn()
import { quickVpn } from '@akcanetwork/x402';

// Auto-install WireGuard + auto-pay + bring up tunnel
const vpn = await quickVpn({
  wallet,
  country: 'US',
  duration: '24h', // '24h' | '7d' | '30d'
});

// All system traffic now goes through VPN
// ...

await vpn.disconnect(); // tunnel down + peer removed
Manual: Step by Step
import { AkcaX402Client, AkcaVpnManager } from '@akcanetwork/x402';

const akca = new AkcaX402Client({ wallet });
const mgr = new AkcaVpnManager();

// 1. Auto-install AmneziaWG/WireGuard if missing
await mgr.ensureInstalled();

// 2. List servers
const servers = await akca.getVpnServers();

// 3. Connect (auto-pays USDC)
const vpn = await akca.connectVpn({
  serverId: servers[0].id,
  duration: '24h'
});

// 4. vpn.config = full WireGuard config text
await mgr.up(vpn.config); // writes config + wg-quick up

// 5. Disconnect
await mgr.down();
await akca.disconnectVpn(vpn.session.id);
Auto-install supports: Ubuntu/Debian (apt), Fedora/RHEL (dnf), Arch (pacman), macOS (brew). Prefers AmneziaWG (DPI bypass), falls back to standard WireGuard. Requires sudo for tunnel management.

🤖 MCP Server — AI Agent Setup

Give Claude, GPT, or any MCP-compatible AI agent anonymous proxy and VPN access. The MCP server loads a local Solana keypair and auto-pays USDC when the agent calls a tool. Your agent doesn't need to know about wallets or payments.

claude_desktop_config.json
{
  "mcpServers": {
    "akca": {
      "command": "npx",
      "args": ["-y", "@akcanetwork/mcp-server"],
      "env": {
        "SOLANA_KEYPAIR_PATH": "~/akca-wallet.json"
      }
    }
  }
}
Available MCP Tools
akca_proxy_fetch
  Proxy any URL through Akca exit nodes
  Input: { url, method?, headers?, country? }
  Cost: 0.001 USDC/request (auto-paid)

akca_vpn_connect
  Start a VPN session, returns WireGuard config
  Input: { serverId, duration? }
  Cost: 0.50 USDC/24h (auto-paid)

akca_list_servers
  List available proxy/VPN exit countries
  Input: {}
  Cost: Free
Env Variable Required Description
SOLANA_KEYPAIR_PATH Yes Path to Solana keypair JSON file with USDC
SOLANA_RPC_URL No Custom RPC endpoint (default: mainnet-beta)
AKCA_API_URL No Custom API URL (default: api.akca.network)
Important: The SOLANA_KEYPAIR_PATH must point to a keypair file with USDC on Solana mainnet. Without it, the MCP server cannot make payments and all paid tools will fail.

🔌 Raw HTTP — Any Language

Don't want to use the SDK? Send raw HTTP requests from any language. Just handle the 402 response yourself.

x402 Flow (curl)
# Step 1: Send request (will get 402)
$ curl -s -X POST https://api.akca.network/x402/proxy/fetch \
  -H "Content-Type: application/json" \
  -H "X-402-Client: true" \
  -d '{"url":"https://example.com"}'

# Response: 402 Payment Required
# { "accepts": [{ "payTo": "ATA...", "maxAmountRequired": "0.001", ... }] }

# Step 2: Send USDC transfer on Solana (your code)
# Transfer 0.001 USDC to the "payTo" ATA address
# Get the transaction signature

# Step 3: Retry with payment proof
$ curl -s -X POST https://api.akca.network/x402/proxy/fetch \
  -H "Content-Type: application/json" \
  -H "X-402-Client: true" \
  -H "X-PAYMENT: 5yNx3...txSignature" \
  -d '{"url":"https://example.com"}'

# Response: 200 OK + Set-Cookie: x402_session=...
Headers: X-402-Client: true (required to see payment details) + X-PAYMENT: <solana-tx-signature> (after paying). The session cookie is returned as Set-Cookie — include it in subsequent requests to avoid re-payment.

📚 API Reference

Base URL: https://api.akca.network

GET
/x402/proxy/servers
Free

List proxy exit countries and load

GET
/x402/vpn/servers
Free

List VPN servers (id, name, country, load)

GET
/x402/vpn/pricing
Free

VPN pricing tiers and durations

POST
/x402/vpn/disconnect
Session required

Disconnect VPN, remove peer. Body: { session_id }

POST
/x402/vpn/heartbeat
Session required

Keep VPN session alive. Body: { session_id }

Proxy vs VPN — Cost Comparison

Choose the optimal mode based on your request volume.

Requests/Day Proxy Cost VPN Cost Winner
10$0.01$0.50Proxy
100$0.10$0.50Proxy
500$0.50$0.50Tie
1,000$1.00$0.50VPN
10,000$10.00$0.50VPN
Smart Selection Logic
async function smartBatch(urls, country) {
  if (urls.length < 500) {
    // Proxy: pay per request
    return Promise.all(
      urls.map(u => akca.fetch(u, { country }))
    );
  }

  // VPN: flat rate, use native fetch
  const vpn = await quickVpn({ wallet, country });
  const results = await Promise.all(
    urls.map(u => fetch(u)) // native fetch through tunnel
  );
  await vpn.disconnect();
  return results;
}
Rule of thumb: < 500 requests → Proxy. 500+ requests → VPN. Proxy needs zero setup. VPN needs WireGuard installed (SDK can auto-install).