Skip to main content

Authentication & Payment

The Cortex API uses the x402 (HTTP 402 Payment Required) protocol for authentication and payment processing. This eliminates the need for traditional API keys and provides a pay-per-request model using USDC on the Base network.

Payment Model

  • Cost: $0.0004 USDC per request
  • Payment Method: USDC on Base network (Chain ID: 8453)
  • Protocol: x402 (HTTP 402 Payment Required)
  • Processing: Automatic via x402 client libraries

Prerequisites

Before using the API, you need:

  1. Crypto Wallet: Any EVM-compatible wallet with USDC
  2. x402 Client Library: Install one of the following:
    • Node.js: npm install x402-fetch or npm install x402-axios
    • Python: pip install x402
    • MCP: npm install x402-mcp (for AI agents)
  3. Private Key: Your wallet's private key for signing transactions

How x402 Works

The x402 protocol automatically handles payments by:

  1. Initial Request: Make a request to the API
  2. Payment Required: Receive a 402 Payment Required response with payment details
  3. Payment Transaction: Create and sign a payment transaction
  4. Retry with Payment: Retry the request with payment headers
  5. API Response: Receive the actual API response

This process is completely transparent when using the x402 client libraries.

Quick Start Examples

JavaScript/Node.js with x402-fetch

import { wrapFetchWithPayment } from "x402-fetch";
import { privateKeyToAccount } from "viem/accounts";

// Create wallet account
const account = privateKeyToAccount(process.env.PRIVATE_KEY);

// Wrap fetch with x402 payment handling
const fetchWithPayment = wrapFetchWithPayment(fetch, account);

// Make paid API request
const response = await fetchWithPayment('https://api.cortex402.xyz/token/0x.../1');
const data = await response.json();
console.log('Token info:', data.data);

Python with x402-requests

from x402.clients.requests import x402_requests
from eth_account import Account

# Create wallet account
account = Account.from_key(os.getenv("PRIVATE_KEY"))

# Create session with payment handling
session = x402_requests(account)

# Make paid API request
response = session.get("https://api.cortex402.xyz/token/0x.../1")
data = response.json()
print("Token info:", data['data'])

Payment Flow Details

Step 1: Initial Request

GET /token/0xA0b86a33E6441b8C4C8C0E4b8b8C4C8C0E4b8b8C4/1

Step 2: Payment Required Response

HTTP/1.1 402 Payment Required
Content-Type: application/json
X-Payment-Required: {
"amount": "400000000000000",
"currency": "USDC",
"recipient": "0x...",
"chainId": 8453,
"nonce": "1234567890"
}

Step 3: Payment Transaction

The x402 client automatically:

  • Creates a USDC transfer transaction
  • Signs it with your private key
  • Broadcasts it to the Base network
  • Waits for confirmation

Step 4: Retry with Payment

GET /token/0xA0b86a33E6441b8C4C8C0E4b8b8C4C8C0E4b8b8C4/1
X-Payment-Proof: 0x...
X-Payment-Tx-Hash: 0x...

Step 5: API Response

HTTP/1.1 200 OK
Content-Type: application/json
X-Payment-Response: {
"txHash": "0x...",
"amount": "400000000000000",
"status": "confirmed"
}

{
"success": true,
"data": {
"address": "0xA0b86a33E6441b8C4C8C0E4b8b8C4C8C0E4b8b8C4",
"symbol": "ETH",
"name": "Ethereum",
"decimals": 18,
"totalSupply": "120000000000000000000000000"
}
}

Error Handling

Payment Errors

{
"success": false,
"error": {
"code": "payment_failed",
"message": "Payment transaction failed",
"details": {
"txHash": "0x...",
"reason": "Insufficient USDC balance"
}
}
}

Common Payment Error Codes

CodeDescriptionSolution
insufficient_balanceNot enough USDC in walletAdd USDC to your wallet
payment_timeoutPayment transaction timed outRetry the request
invalid_paymentPayment verification failedCheck transaction details
network_errorBlockchain network errorCheck network status

Security Best Practices

Wallet Security

  • Never share your private key with anyone
  • Use hardware wallets for production applications
  • Store private keys securely using environment variables
  • Use testnet first to verify your integration

Payment Security

  • Verify payment amounts before confirming transactions
  • Monitor your USDC balance to ensure sufficient funds
  • Use appropriate gas limits for payment transactions
  • Keep transaction receipts for accounting purposes

Development Security

// ✅ Good: Use environment variables
const account = privateKeyToAccount(process.env.PRIVATE_KEY);

// ❌ Bad: Hardcode private key
const account = privateKeyToAccount("0x1234567890abcdef...");

Cost Management

Understanding Costs

  • Each API request costs exactly $0.0004 USDC
  • No monthly fees or subscription costs
  • Pay only for what you use
  • Costs are transparent and predictable

Cost Optimization Tips

  1. Cache responses when appropriate
  2. Use batch operations when available
  3. Implement request deduplication
  4. Monitor usage patterns
  5. Use search with appropriate limits

Usage Monitoring

// Example: Track API usage and costs
class UsageTracker {
constructor() {
this.requests = 0;
this.cost = 0;
}

trackRequest(paymentResponse) {
this.requests++;
this.cost += 0.0004; // $0.0004 per request

console.log(`Requests: ${this.requests}, Total Cost: $${this.cost.toFixed(4)}`);
}
}

Testing

Testnet Usage

For development and testing, use Base Sepolia testnet:

// Use testnet for development
const account = privateKeyToAccount(process.env.PRIVATE_KEY);
const fetchWithPayment = wrapFetchWithPayment(fetch, account, {
network: "base-sepolia" // Use testnet
});

Test USDC

Get test USDC from Base Sepolia faucets:

Troubleshooting

Common Issues

Issue: "Insufficient USDC balance"

  • Solution: Add USDC to your wallet on Base network

Issue: "Payment transaction failed"

  • Solution: Check gas settings and network connectivity

Issue: "Invalid payment proof"

  • Solution: Ensure you're using the correct network (Base mainnet)

Issue: "x402 client not found"

  • Solution: Install the appropriate x402 client library

Debug Mode

Enable debug logging to troubleshoot payment issues:

// Enable debug mode
const fetchWithPayment = wrapFetchWithPayment(fetch, account, {
debug: true // Enable detailed logging
});

Next Steps